Skip to content

Commit 50e1d15

Browse files
committed
Do not fail to load ChannelManager when we see claiming payments
When we begin claiming a payment, we move the tracking of it from `claimable_payments` to `claiming_payments`. This ensures we only ever have one payment which is in the process of being claimed with a given payment hash at a time and lets us keep track of when all parts have been claimed with their `ChannelMonitor`s. However, on startup, we check that failing to move a payment from `claimable_payments` to `claiming_payments` implies that it is not present in `claiming_payments`. This is fine if the payment doesn't exist, but if the payment has already started being claimed, this will fail and we'll refuse to deserialize the `ChannelManager` (with a `debug_assert` failure in debug mode). Here we resolve this by checking if a payment is already being claimed before we attempt to initiate claiming and skip the failing check in that case.
1 parent b4d5fe2 commit 50e1d15

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14237,6 +14237,22 @@ where
1423714237
if payment_claim.mpp_parts.is_empty() {
1423814238
return Err(DecodeError::InvalidValue);
1423914239
}
14240+
{
14241+
let payments = channel_manager.claimable_payments.lock().unwrap();
14242+
if !payments.claimable_payments.contains_key(&payment_hash) {
14243+
if let Some(payment) = payments.pending_claiming_payments.get(&payment_hash) {
14244+
if payment.payment_id == payment_claim.claiming_payment.payment_id {
14245+
// If this payment already exists and was marked as
14246+
// being-claimed then the serialized state must contain all
14247+
// of the pending `ChannelMonitorUpdate`s required to get
14248+
// the preimage on disk in all MPP parts. Thus we can skip
14249+
// the replay below.
14250+
continue;
14251+
}
14252+
}
14253+
}
14254+
}
14255+
1424014256
let mut channels_without_preimage = payment_claim.mpp_parts.iter()
1424114257
.map(|htlc_info| (htlc_info.counterparty_node_id, htlc_info.funding_txo, htlc_info.channel_id))
1424214258
.collect::<Vec<_>>();

lightning/src/ln/reload_tests.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ fn test_forwardable_regen() {
781781
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage_2);
782782
}
783783

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

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

806806
let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs);
807807

@@ -876,7 +876,14 @@ fn do_test_partial_claim_before_restart(persist_both_monitors: bool) {
876876
}
877877

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

881888
// Until the startup background events are processed (in `get_and_clear_pending_events`,
882889
// below), the preimage is not copied to the non-persisted monitor...
@@ -971,8 +978,10 @@ fn do_test_partial_claim_before_restart(persist_both_monitors: bool) {
971978

972979
#[test]
973980
fn test_partial_claim_before_restart() {
974-
do_test_partial_claim_before_restart(false);
975-
do_test_partial_claim_before_restart(true);
981+
do_test_partial_claim_before_restart(false, false);
982+
do_test_partial_claim_before_restart(false, true);
983+
do_test_partial_claim_before_restart(true, false);
984+
do_test_partial_claim_before_restart(true, true);
976985
}
977986

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

0 commit comments

Comments
 (0)