Skip to content

Commit db1681b

Browse files
Merge pull request #3772 from TheBlueMatt/2025-05-chanman-double-restart-claim-fail
Do not fail to load `ChannelManager` when we see claiming payments
2 parents 5316257 + 21f829b commit db1681b

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

lightning/src/ln/channelmanager.rs

+16
Original file line numberDiff line numberDiff line change
@@ -14835,6 +14835,22 @@ where
1483514835
if payment_claim.mpp_parts.is_empty() {
1483614836
return Err(DecodeError::InvalidValue);
1483714837
}
14838+
{
14839+
let payments = channel_manager.claimable_payments.lock().unwrap();
14840+
if !payments.claimable_payments.contains_key(&payment_hash) {
14841+
if let Some(payment) = payments.pending_claiming_payments.get(&payment_hash) {
14842+
if payment.payment_id == payment_claim.claiming_payment.payment_id {
14843+
// If this payment already exists and was marked as
14844+
// being-claimed then the serialized state must contain all
14845+
// of the pending `ChannelMonitorUpdate`s required to get
14846+
// the preimage on disk in all MPP parts. Thus we can skip
14847+
// the replay below.
14848+
continue;
14849+
}
14850+
}
14851+
}
14852+
}
14853+
1483814854
let mut channels_without_preimage = payment_claim.mpp_parts.iter()
1483914855
.map(|htlc_info| (htlc_info.counterparty_node_id, htlc_info.funding_txo, htlc_info.channel_id))
1484014856
.collect::<Vec<_>>();

lightning/src/ln/reload_tests.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ fn test_forwardable_regen() {
783783
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage_2);
784784
}
785785

786-
fn do_test_partial_claim_before_restart(persist_both_monitors: bool) {
786+
fn do_test_partial_claim_before_restart(persist_both_monitors: bool, double_restart: bool) {
787787
// Test what happens if a node receives an MPP payment, claims it, but crashes before
788788
// persisting the ChannelManager. If `persist_both_monitors` is false, also crash after only
789789
// updating one of the two channels' ChannelMonitors. As a result, on startup, we'll (a) still
@@ -799,11 +799,11 @@ fn do_test_partial_claim_before_restart(persist_both_monitors: bool) {
799799
// definitely claimed.
800800
let chanmon_cfgs = create_chanmon_cfgs(4);
801801
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
802-
let persister;
803-
let new_chain_monitor;
802+
let (persist_d_1, persist_d_2);
803+
let (chain_d_1, chain_d_2);
804804

805805
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
806-
let nodes_3_deserialized;
806+
let (node_d_1, node_d_2);
807807

808808
let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs);
809809

@@ -878,7 +878,14 @@ fn do_test_partial_claim_before_restart(persist_both_monitors: bool) {
878878
}
879879

880880
// Now restart nodes[3].
881-
reload_node!(nodes[3], original_manager, &[&updated_monitor.0, &original_monitor.0], persister, new_chain_monitor, nodes_3_deserialized);
881+
reload_node!(nodes[3], original_manager.clone(), &[&updated_monitor.0, &original_monitor.0], persist_d_1, chain_d_1, node_d_1);
882+
883+
if double_restart {
884+
// Previously, we had a bug where we'd fail to reload if we re-persist the `ChannelManager`
885+
// without updating any `ChannelMonitor`s as we'd fail to double-initiate the claim replay.
886+
// We test that here ensuring that we can reload again.
887+
reload_node!(nodes[3], node_d_1.encode(), &[&updated_monitor.0, &original_monitor.0], persist_d_2, chain_d_2, node_d_2);
888+
}
882889

883890
// Until the startup background events are processed (in `get_and_clear_pending_events`,
884891
// below), the preimage is not copied to the non-persisted monitor...
@@ -973,8 +980,10 @@ fn do_test_partial_claim_before_restart(persist_both_monitors: bool) {
973980

974981
#[test]
975982
fn test_partial_claim_before_restart() {
976-
do_test_partial_claim_before_restart(false);
977-
do_test_partial_claim_before_restart(true);
983+
do_test_partial_claim_before_restart(false, false);
984+
do_test_partial_claim_before_restart(false, true);
985+
do_test_partial_claim_before_restart(true, false);
986+
do_test_partial_claim_before_restart(true, true);
978987
}
979988

980989
fn do_forwarded_payment_no_manager_persistence(use_cs_commitment: bool, claim_htlc: bool, use_intercept: bool) {

0 commit comments

Comments
 (0)