Skip to content

Commit 8dda7a1

Browse files
jkczyzclaude
andcommitted
Emit DiscardFunding before SpliceFailed
Reverse the event ordering at all emission sites so that Event::DiscardFunding is emitted before Event::SpliceFailed. If the user retries the splice when handling SpliceFailed, the contributed inputs would still be locked. A subsequent DiscardFunding would then incorrectly unlock inputs that are now committed to the new attempt. Emitting DiscardFunding first avoids this by ensuring inputs are unlocked before any retry occurs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 165f8a9 commit 8dda7a1

3 files changed

Lines changed: 140 additions & 140 deletions

File tree

lightning/src/ln/channelmanager.rs

Lines changed: 97 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -4108,16 +4108,6 @@ impl<
41084108

41094109
if let Some(splice_funding_failed) = splice_funding_failed {
41104110
let mut pending_events = self.pending_events.lock().unwrap();
4111-
pending_events.push_back((
4112-
events::Event::SpliceFailed {
4113-
channel_id: *chan_id,
4114-
counterparty_node_id: *counterparty_node_id,
4115-
user_channel_id: chan.context().get_user_id(),
4116-
contribution: splice_funding_failed.contribution,
4117-
reason: events::NegotiationFailureReason::ChannelClosing,
4118-
},
4119-
None,
4120-
));
41214111
pending_events.push_back((
41224112
events::Event::DiscardFunding {
41234113
channel_id: *chan_id,
@@ -4128,6 +4118,16 @@ impl<
41284118
},
41294119
None,
41304120
));
4121+
pending_events.push_back((
4122+
events::Event::SpliceFailed {
4123+
channel_id: *chan_id,
4124+
counterparty_node_id: *counterparty_node_id,
4125+
user_channel_id: chan.context().get_user_id(),
4126+
contribution: splice_funding_failed.contribution,
4127+
reason: events::NegotiationFailureReason::ChannelClosing,
4128+
},
4129+
None,
4130+
));
41314131
}
41324132

41334133
// We can send the `shutdown` message before updating the `ChannelMonitor`
@@ -4414,16 +4414,6 @@ impl<
44144414
));
44154415

44164416
if let Some(splice_funding_failed) = shutdown_res.splice_funding_failed.take() {
4417-
pending_events.push_back((
4418-
events::Event::SpliceFailed {
4419-
channel_id: shutdown_res.channel_id,
4420-
counterparty_node_id: shutdown_res.counterparty_node_id,
4421-
user_channel_id: shutdown_res.user_channel_id,
4422-
contribution: splice_funding_failed.contribution,
4423-
reason: events::NegotiationFailureReason::ChannelClosing,
4424-
},
4425-
None,
4426-
));
44274417
pending_events.push_back((
44284418
events::Event::DiscardFunding {
44294419
channel_id: shutdown_res.channel_id,
@@ -4434,6 +4424,16 @@ impl<
44344424
},
44354425
None,
44364426
));
4427+
pending_events.push_back((
4428+
events::Event::SpliceFailed {
4429+
channel_id: shutdown_res.channel_id,
4430+
counterparty_node_id: shutdown_res.counterparty_node_id,
4431+
user_channel_id: shutdown_res.user_channel_id,
4432+
contribution: splice_funding_failed.contribution,
4433+
reason: events::NegotiationFailureReason::ChannelClosing,
4434+
},
4435+
None,
4436+
));
44374437
}
44384438

44394439
if let Some(transaction) = shutdown_res.unbroadcasted_funding_tx {
@@ -4920,16 +4920,6 @@ impl<
49204920

49214921
if let Some(splice_funding_failed) = splice_funding_failed {
49224922
let pending_events = &mut self.pending_events.lock().unwrap();
4923-
pending_events.push_back((
4924-
events::Event::SpliceFailed {
4925-
channel_id: *channel_id,
4926-
counterparty_node_id: *counterparty_node_id,
4927-
user_channel_id: chan.context.get_user_id(),
4928-
contribution: splice_funding_failed.contribution,
4929-
reason: events::NegotiationFailureReason::LocallyAbandoned,
4930-
},
4931-
None,
4932-
));
49334923
pending_events.push_back((
49344924
events::Event::DiscardFunding {
49354925
channel_id: *channel_id,
@@ -4940,6 +4930,16 @@ impl<
49404930
},
49414931
None,
49424932
));
4933+
pending_events.push_back((
4934+
events::Event::SpliceFailed {
4935+
channel_id: *channel_id,
4936+
counterparty_node_id: *counterparty_node_id,
4937+
user_channel_id: chan.context.get_user_id(),
4938+
contribution: splice_funding_failed.contribution,
4939+
reason: events::NegotiationFailureReason::LocallyAbandoned,
4940+
},
4941+
None,
4942+
));
49434943
}
49444944

49454945
Ok(())
@@ -6616,16 +6616,6 @@ impl<
66166616
reason,
66176617
) => {
66186618
let pending_events = &mut self.pending_events.lock().unwrap();
6619-
pending_events.push_back((
6620-
events::Event::SpliceFailed {
6621-
channel_id,
6622-
counterparty_node_id,
6623-
user_channel_id,
6624-
reason,
6625-
contribution,
6626-
},
6627-
None,
6628-
));
66296619
if !contributed_inputs.is_empty() || !contributed_outputs.is_empty() {
66306620
pending_events.push_back((
66316621
events::Event::DiscardFunding {
@@ -6638,6 +6628,16 @@ impl<
66386628
None,
66396629
));
66406630
}
6631+
pending_events.push_back((
6632+
events::Event::SpliceFailed {
6633+
channel_id,
6634+
counterparty_node_id,
6635+
user_channel_id,
6636+
reason,
6637+
contribution,
6638+
},
6639+
None,
6640+
));
66416641
},
66426642
}
66436643
}
@@ -11851,16 +11851,6 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1185111851
}) => {
1185211852
if let Some(splice_funding_failed) = splice_funding_failed {
1185311853
let pending_events = &mut self.pending_events.lock().unwrap();
11854-
pending_events.push_back((
11855-
events::Event::SpliceFailed {
11856-
channel_id,
11857-
counterparty_node_id: *counterparty_node_id,
11858-
user_channel_id: channel.context().get_user_id(),
11859-
contribution: splice_funding_failed.contribution.clone(),
11860-
reason: events::NegotiationFailureReason::NegotiationError,
11861-
},
11862-
None,
11863-
));
1186411854
pending_events.push_back((
1186511855
events::Event::DiscardFunding {
1186611856
channel_id,
@@ -11871,6 +11861,16 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1187111861
},
1187211862
None,
1187311863
));
11864+
pending_events.push_back((
11865+
events::Event::SpliceFailed {
11866+
channel_id,
11867+
counterparty_node_id: *counterparty_node_id,
11868+
user_channel_id: channel.context().get_user_id(),
11869+
contribution: splice_funding_failed.contribution.clone(),
11870+
reason: events::NegotiationFailureReason::NegotiationError,
11871+
},
11872+
None,
11873+
));
1187411874
}
1187511875
debug_assert!(!exited_quiescence || matches!(err, ChannelError::Abort(_)));
1187611876

@@ -12010,16 +12010,6 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1201012010
}) => {
1201112011
if let Some(splice_funding_failed) = splice_funding_failed {
1201212012
let pending_events = &mut self.pending_events.lock().unwrap();
12013-
pending_events.push_back((
12014-
events::Event::SpliceFailed {
12015-
channel_id: msg.channel_id,
12016-
counterparty_node_id,
12017-
user_channel_id: chan.context().get_user_id(),
12018-
contribution: splice_funding_failed.contribution.clone(),
12019-
reason: events::NegotiationFailureReason::NegotiationError,
12020-
},
12021-
None,
12022-
));
1202312013
pending_events.push_back((
1202412014
events::Event::DiscardFunding {
1202512015
channel_id: msg.channel_id,
@@ -12030,6 +12020,16 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1203012020
},
1203112021
None,
1203212022
));
12023+
pending_events.push_back((
12024+
events::Event::SpliceFailed {
12025+
channel_id: msg.channel_id,
12026+
counterparty_node_id,
12027+
user_channel_id: chan.context().get_user_id(),
12028+
contribution: splice_funding_failed.contribution.clone(),
12029+
reason: events::NegotiationFailureReason::NegotiationError,
12030+
},
12031+
None,
12032+
));
1203312033
}
1203412034
debug_assert!(!exited_quiescence || matches!(err, ChannelError::Abort(_)));
1203512035

@@ -12180,16 +12180,6 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1218012180

1218112181
if let Some(splice_funding_failed) = splice_failed {
1218212182
let pending_events = &mut self.pending_events.lock().unwrap();
12183-
pending_events.push_back((
12184-
events::Event::SpliceFailed {
12185-
channel_id: msg.channel_id,
12186-
counterparty_node_id: *counterparty_node_id,
12187-
user_channel_id: chan_entry.get().context().get_user_id(),
12188-
contribution: splice_funding_failed.contribution,
12189-
reason: events::NegotiationFailureReason::CounterpartyAborted,
12190-
},
12191-
None,
12192-
));
1219312183
pending_events.push_back((
1219412184
events::Event::DiscardFunding {
1219512185
channel_id: msg.channel_id,
@@ -12200,6 +12190,16 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1220012190
},
1220112191
None,
1220212192
));
12193+
pending_events.push_back((
12194+
events::Event::SpliceFailed {
12195+
channel_id: msg.channel_id,
12196+
counterparty_node_id: *counterparty_node_id,
12197+
user_channel_id: chan_entry.get().context().get_user_id(),
12198+
contribution: splice_funding_failed.contribution,
12199+
reason: events::NegotiationFailureReason::CounterpartyAborted,
12200+
},
12201+
None,
12202+
));
1220312203
}
1220412204

1220512205
let holding_cell_res = if exited_quiescence {
@@ -12328,16 +12328,6 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1232812328

1232912329
if let Some(splice_funding_failed) = splice_funding_failed {
1233012330
let mut pending_events = self.pending_events.lock().unwrap();
12331-
pending_events.push_back((
12332-
events::Event::SpliceFailed {
12333-
channel_id: msg.channel_id,
12334-
counterparty_node_id: *counterparty_node_id,
12335-
user_channel_id: chan.context().get_user_id(),
12336-
contribution: splice_funding_failed.contribution,
12337-
reason: events::NegotiationFailureReason::ChannelClosing,
12338-
},
12339-
None,
12340-
));
1234112331
pending_events.push_back((
1234212332
events::Event::DiscardFunding {
1234312333
channel_id: msg.channel_id,
@@ -12348,6 +12338,16 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1234812338
},
1234912339
None,
1235012340
));
12341+
pending_events.push_back((
12342+
events::Event::SpliceFailed {
12343+
channel_id: msg.channel_id,
12344+
counterparty_node_id: *counterparty_node_id,
12345+
user_channel_id: chan.context().get_user_id(),
12346+
contribution: splice_funding_failed.contribution,
12347+
reason: events::NegotiationFailureReason::ChannelClosing,
12348+
},
12349+
None,
12350+
));
1235112351
}
1235212352

1235312353
if let Some(msg) = shutdown {
@@ -15445,20 +15445,20 @@ impl<
1544515445
chan.peer_disconnected_is_resumable(&&logger);
1544615446

1544715447
if let Some(splice_funding_failed) = splice_funding_failed {
15448-
splice_failed_events.push(events::Event::SpliceFailed {
15449-
channel_id: chan.context().channel_id(),
15450-
counterparty_node_id,
15451-
user_channel_id: chan.context().get_user_id(),
15452-
contribution: splice_funding_failed.contribution,
15453-
reason: events::NegotiationFailureReason::PeerDisconnected,
15454-
});
1545515448
splice_failed_events.push(events::Event::DiscardFunding {
1545615449
channel_id: chan.context().channel_id(),
1545715450
funding_info: FundingInfo::Contribution {
1545815451
inputs: splice_funding_failed.contributed_inputs,
1545915452
outputs: splice_funding_failed.contributed_outputs,
1546015453
},
1546115454
});
15455+
splice_failed_events.push(events::Event::SpliceFailed {
15456+
channel_id: chan.context().channel_id(),
15457+
counterparty_node_id,
15458+
user_channel_id: chan.context().get_user_id(),
15459+
contribution: splice_funding_failed.contribution,
15460+
reason: events::NegotiationFailureReason::PeerDisconnected,
15461+
});
1546215462
}
1546315463

1546415464
if is_resumable {
@@ -18116,16 +18116,6 @@ impl<
1811618116
for peer_state in peer_states.iter() {
1811718117
for chan in peer_state.channel_by_id.values().filter_map(Channel::as_funded) {
1811818118
if let Some(splice_funding_failed) = chan.maybe_splice_funding_failed() {
18119-
events.push_back((
18120-
events::Event::SpliceFailed {
18121-
channel_id: chan.context.channel_id(),
18122-
counterparty_node_id: chan.context.get_counterparty_node_id(),
18123-
user_channel_id: chan.context.get_user_id(),
18124-
reason: events::NegotiationFailureReason::PeerDisconnected,
18125-
contribution: splice_funding_failed.contribution,
18126-
},
18127-
None,
18128-
));
1812918119
events.push_back((
1813018120
events::Event::DiscardFunding {
1813118121
channel_id: chan.context().channel_id(),
@@ -18136,6 +18126,16 @@ impl<
1813618126
},
1813718127
None,
1813818128
));
18129+
events.push_back((
18130+
events::Event::SpliceFailed {
18131+
channel_id: chan.context.channel_id(),
18132+
counterparty_node_id: chan.context.get_counterparty_node_id(),
18133+
user_channel_id: chan.context.get_user_id(),
18134+
reason: events::NegotiationFailureReason::PeerDisconnected,
18135+
contribution: splice_funding_failed.contribution,
18136+
},
18137+
None,
18138+
));
1813918139
}
1814018140
}
1814118141
}

lightning/src/ln/functional_test_utils.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3248,18 +3248,10 @@ pub fn expect_splice_failed_events<'a, 'b, 'c, 'd>(
32483248
let events = node.node.get_and_clear_pending_events();
32493249
assert_eq!(events.len(), 2);
32503250
match &events[0] {
3251-
Event::SpliceFailed { channel_id, reason, contribution, .. } => {
3252-
assert_eq!(*expected_channel_id, *channel_id);
3253-
assert_eq!(*reason, expected_reason);
3254-
assert_eq!(contribution.as_ref(), Some(&funding_contribution));
3255-
},
3256-
_ => panic!("Unexpected event"),
3257-
}
3258-
match &events[1] {
32593251
Event::DiscardFunding { funding_info, .. } => {
32603252
if let FundingInfo::Contribution { inputs, outputs } = &funding_info {
32613253
let (expected_inputs, expected_outputs) =
3262-
funding_contribution.into_contributed_inputs_and_outputs();
3254+
funding_contribution.clone().into_contributed_inputs_and_outputs();
32633255
assert_eq!(*inputs, expected_inputs);
32643256
assert_eq!(*outputs, expected_outputs);
32653257
} else {
@@ -3268,6 +3260,14 @@ pub fn expect_splice_failed_events<'a, 'b, 'c, 'd>(
32683260
},
32693261
_ => panic!("Unexpected event"),
32703262
}
3263+
match &events[1] {
3264+
Event::SpliceFailed { channel_id, reason, contribution, .. } => {
3265+
assert_eq!(*expected_channel_id, *channel_id);
3266+
assert_eq!(*reason, expected_reason);
3267+
assert_eq!(contribution.as_ref(), Some(&funding_contribution));
3268+
},
3269+
_ => panic!("Unexpected event"),
3270+
}
32713271
}
32723272

32733273
#[cfg(any(test, ldk_bench, feature = "_test_utils"))]

0 commit comments

Comments
 (0)