Skip to content

Commit da6e569

Browse files
committed
Handle duplicate payment claims during initialization
In the next commit we'll start using (much of) the normal HTLC claim pipeline to replay payment claims on startup. In order to do so, however, we have to properly handle cases where we get a `DuplicateClaim` back from the channel for an inbound-payment HTLC. Here we do so, handling the `MonitorUpdateCompletionAction` and allowing an already-completed RAA blocker.
1 parent c323950 commit da6e569

File tree

1 file changed

+37
-25
lines changed

1 file changed

+37
-25
lines changed

lightning/src/ln/channelmanager.rs

+37-25
Original file line numberDiff line numberDiff line change
@@ -6955,7 +6955,16 @@ where
69556955
UpdateFulfillCommitFetch::DuplicateClaim {} => {
69566956
let (action_opt, raa_blocker_opt) = completion_action(None, true);
69576957
if let Some(raa_blocker) = raa_blocker_opt {
6958-
debug_assert!(peer_state.actions_blocking_raa_monitor_updates.get(&chan_id).unwrap().contains(&raa_blocker));
6958+
// If we're making a claim during startup, its a replay of a
6959+
// payment claim from a `ChannelMonitor`. In some cases (MPP or
6960+
// if the HTLC was only recently removed) we make such claims
6961+
// after an HTLC has been removed from a channel entirely, and
6962+
// thus the RAA blocker has long since completed.
6963+
//
6964+
// In any other case, the RAA blocker must still be present and
6965+
// blocking RAAs.
6966+
debug_assert!(during_init ||
6967+
peer_state.actions_blocking_raa_monitor_updates.get(&chan_id).unwrap().contains(&raa_blocker));
69596968
}
69606969
let action = if let Some(action) = action_opt {
69616970
action
@@ -6967,38 +6976,41 @@ where
69676976

69686977
log_trace!(logger, "Completing monitor update completion action for channel {} as claim was redundant: {:?}",
69696978
chan_id, action);
6970-
let (node_id, _funding_outpoint, channel_id, blocker) =
69716979
if let MonitorUpdateCompletionAction::FreeOtherChannelImmediately {
69726980
downstream_counterparty_node_id: node_id,
6973-
downstream_funding_outpoint: funding_outpoint,
6981+
downstream_funding_outpoint: _,
69746982
blocking_action: blocker, downstream_channel_id: channel_id,
69756983
} = action {
6976-
(node_id, funding_outpoint, channel_id, blocker)
6984+
if let Some(peer_state_mtx) = per_peer_state.get(&node_id) {
6985+
let mut peer_state = peer_state_mtx.lock().unwrap();
6986+
if let Some(blockers) = peer_state
6987+
.actions_blocking_raa_monitor_updates
6988+
.get_mut(&channel_id)
6989+
{
6990+
let mut found_blocker = false;
6991+
blockers.retain(|iter| {
6992+
// Note that we could actually be blocked, in
6993+
// which case we need to only remove the one
6994+
// blocker which was added duplicatively.
6995+
let first_blocker = !found_blocker;
6996+
if *iter == blocker { found_blocker = true; }
6997+
*iter != blocker || !first_blocker
6998+
});
6999+
debug_assert!(found_blocker);
7000+
}
7001+
} else {
7002+
debug_assert!(false);
7003+
}
7004+
} else if matches!(action, MonitorUpdateCompletionAction::PaymentClaimed { .. }) {
7005+
debug_assert!(during_init,
7006+
"Duplicate claims should always either be for forwarded payments(freeing another channel immediately) or during init (for claim replay)");
7007+
mem::drop(per_peer_state);
7008+
self.handle_monitor_update_completion_actions([action]);
69777009
} else {
69787010
debug_assert!(false,
6979-
"Duplicate claims should always free another channel immediately");
7011+
"Duplicate claims should always either be for forwarded payments(freeing another channel immediately) or during init (for claim replay)");
69807012
return;
69817013
};
6982-
if let Some(peer_state_mtx) = per_peer_state.get(&node_id) {
6983-
let mut peer_state = peer_state_mtx.lock().unwrap();
6984-
if let Some(blockers) = peer_state
6985-
.actions_blocking_raa_monitor_updates
6986-
.get_mut(&channel_id)
6987-
{
6988-
let mut found_blocker = false;
6989-
blockers.retain(|iter| {
6990-
// Note that we could actually be blocked, in
6991-
// which case we need to only remove the one
6992-
// blocker which was added duplicatively.
6993-
let first_blocker = !found_blocker;
6994-
if *iter == blocker { found_blocker = true; }
6995-
*iter != blocker || !first_blocker
6996-
});
6997-
debug_assert!(found_blocker);
6998-
}
6999-
} else {
7000-
debug_assert!(false);
7001-
}
70027014
}
70037015
}
70047016
}

0 commit comments

Comments
 (0)