Skip to content

Commit 0a3d19f

Browse files
committed
Don't pause events for chainsync persistence
We used to wait on ChannelMonitor persistence to avoid duplicate payment events. But this can still happen in cases where ChannelMonitor handed the event to ChannelManager and we did not persist ChannelManager after event handling. It is expected to receive payment duplicate events and clients should handle these events in an idempotent manner. Removing this hold-up of events simplifies the logic and makes it easier to not persist ChannelMonitors on every block connect.
1 parent 5e41425 commit 0a3d19f

File tree

2 files changed

+29
-120
lines changed

2 files changed

+29
-120
lines changed

lightning/src/chain/chainmonitor.rs

+11-92
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use bitcoin::hash_types::{Txid, BlockHash};
2929
use crate::chain;
3030
use crate::chain::{ChannelMonitorUpdateStatus, Filter, WatchedOutput};
3131
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
32-
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, Balance, MonitorEvent, TransactionOutputs, WithChannelMonitor, LATENCY_GRACE_PERIOD_BLOCKS};
32+
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, Balance, MonitorEvent, TransactionOutputs, WithChannelMonitor};
3333
use crate::chain::transaction::{OutPoint, TransactionData};
3434
use crate::ln::ChannelId;
3535
use crate::sign::ecdsa::WriteableEcdsaChannelSigner;
@@ -851,21 +851,12 @@ where C::Target: chain::Filter,
851851
fn release_pending_monitor_events(&self) -> Vec<(OutPoint, ChannelId, Vec<MonitorEvent>, Option<PublicKey>)> {
852852
let mut pending_monitor_events = self.pending_monitor_events.lock().unwrap().split_off(0);
853853
for monitor_state in self.monitors.read().unwrap().values() {
854-
let logger = WithChannelMonitor::from(&self.logger, &monitor_state.monitor);
855-
let is_pending_monitor_update = monitor_state.has_pending_chainsync_updates(&monitor_state.pending_monitor_updates.lock().unwrap());
856-
if !is_pending_monitor_update || monitor_state.last_chain_persist_height.load(Ordering::Acquire) + LATENCY_GRACE_PERIOD_BLOCKS as usize <= self.highest_chain_height.load(Ordering::Acquire) {
857-
if is_pending_monitor_update {
858-
log_error!(logger, "A ChannelMonitor sync took longer than {} blocks to complete.", LATENCY_GRACE_PERIOD_BLOCKS);
859-
log_error!(logger, " To avoid funds-loss, we are allowing monitor updates to be released.");
860-
log_error!(logger, " This may cause duplicate payment events to be generated.");
861-
}
862-
let monitor_events = monitor_state.monitor.get_and_clear_pending_monitor_events();
863-
if monitor_events.len() > 0 {
864-
let monitor_outpoint = monitor_state.monitor.get_funding_txo().0;
865-
let monitor_channel_id = monitor_state.monitor.channel_id();
866-
let counterparty_node_id = monitor_state.monitor.get_counterparty_node_id();
867-
pending_monitor_events.push((monitor_outpoint, monitor_channel_id, monitor_events, counterparty_node_id));
868-
}
854+
let monitor_events = monitor_state.monitor.get_and_clear_pending_monitor_events();
855+
if monitor_events.len() > 0 {
856+
let monitor_outpoint = monitor_state.monitor.get_funding_txo().0;
857+
let monitor_channel_id = monitor_state.monitor.channel_id();
858+
let counterparty_node_id = monitor_state.monitor.get_counterparty_node_id();
859+
pending_monitor_events.push((monitor_outpoint, monitor_channel_id, monitor_events, counterparty_node_id));
869860
}
870861
}
871862
pending_monitor_events
@@ -902,15 +893,12 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L
902893
#[cfg(test)]
903894
mod tests {
904895
use crate::check_added_monitors;
905-
use crate::{expect_payment_claimed, expect_payment_path_successful, get_event_msg};
906-
use crate::{get_htlc_update_msgs, get_local_commitment_txn, get_revoke_commit_msgs, get_route_and_payment_hash, unwrap_send_err};
907-
use crate::chain::{ChannelMonitorUpdateStatus, Confirm, Watch};
908-
use crate::chain::channelmonitor::LATENCY_GRACE_PERIOD_BLOCKS;
896+
use crate::{expect_payment_path_successful, get_event_msg};
897+
use crate::{get_htlc_update_msgs, get_revoke_commit_msgs};
898+
use crate::chain::{ChannelMonitorUpdateStatus, Watch};
909899
use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider};
910-
use crate::ln::channelmanager::{PaymentSendFailure, PaymentId, RecipientOnionFields};
911900
use crate::ln::functional_test_utils::*;
912901
use crate::ln::msgs::ChannelMessageHandler;
913-
use crate::util::errors::APIError;
914902

915903
#[test]
916904
fn test_async_ooo_offchain_updates() {
@@ -1017,76 +1005,6 @@ mod tests {
10171005
check_added_monitors!(nodes[0], 1);
10181006
}
10191007

1020-
fn do_chainsync_pauses_events(block_timeout: bool) {
1021-
// When a chainsync monitor update occurs, any MonitorUpdates should be held before being
1022-
// passed upstream to a `ChannelManager` via `Watch::release_pending_monitor_events`. This
1023-
// tests that behavior, as well as some ways it might go wrong.
1024-
let chanmon_cfgs = create_chanmon_cfgs(2);
1025-
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
1026-
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
1027-
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
1028-
let channel = create_announced_chan_between_nodes(&nodes, 0, 1);
1029-
1030-
// Get a route for later and rebalance the channel somewhat
1031-
send_payment(&nodes[0], &[&nodes[1]], 10_000_000);
1032-
let (route, second_payment_hash, _, second_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], 100_000);
1033-
1034-
// First route a payment that we will claim on chain and give the recipient the preimage.
1035-
let (payment_preimage, payment_hash, ..) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
1036-
nodes[1].node.claim_funds(payment_preimage);
1037-
expect_payment_claimed!(nodes[1], payment_hash, 1_000_000);
1038-
nodes[1].node.get_and_clear_pending_msg_events();
1039-
check_added_monitors!(nodes[1], 1);
1040-
let remote_txn = get_local_commitment_txn!(nodes[1], channel.2);
1041-
assert_eq!(remote_txn.len(), 2);
1042-
1043-
// Temp-fail the block connection which will hold the channel-closed event
1044-
chanmon_cfgs[0].persister.chain_sync_monitor_persistences.lock().unwrap().clear();
1045-
chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
1046-
1047-
// Connect B's commitment transaction, but only to the ChainMonitor/ChannelMonitor. The
1048-
// channel is now closed, but the ChannelManager doesn't know that yet.
1049-
let new_header = create_dummy_header(nodes[0].best_block_info().0, 0);
1050-
nodes[0].chain_monitor.chain_monitor.transactions_confirmed(&new_header,
1051-
&[(0, &remote_txn[0]), (1, &remote_txn[1])], nodes[0].best_block_info().1 + 1);
1052-
assert!(nodes[0].chain_monitor.release_pending_monitor_events().is_empty());
1053-
nodes[0].chain_monitor.chain_monitor.best_block_updated(&new_header, nodes[0].best_block_info().1 + 1);
1054-
assert!(nodes[0].chain_monitor.release_pending_monitor_events().is_empty());
1055-
1056-
// If the ChannelManager tries to update the channel, however, the ChainMonitor will pass
1057-
// the update through to the ChannelMonitor which will refuse it (as the channel is closed).
1058-
chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
1059-
unwrap_send_err!(nodes[0].node.send_payment_with_route(&route, second_payment_hash,
1060-
RecipientOnionFields::secret_only(second_payment_secret), PaymentId(second_payment_hash.0)
1061-
), false, APIError::MonitorUpdateInProgress, {});
1062-
check_added_monitors!(nodes[0], 1);
1063-
1064-
// However, as the ChainMonitor is still waiting for the original persistence to complete,
1065-
// it won't yet release the MonitorEvents.
1066-
assert!(nodes[0].chain_monitor.release_pending_monitor_events().is_empty());
1067-
1068-
if block_timeout {
1069-
// After three blocks, pending MontiorEvents should be released either way.
1070-
let latest_header = create_dummy_header(nodes[0].best_block_info().0, 0);
1071-
nodes[0].chain_monitor.chain_monitor.best_block_updated(&latest_header, nodes[0].best_block_info().1 + LATENCY_GRACE_PERIOD_BLOCKS);
1072-
} else {
1073-
let persistences = chanmon_cfgs[0].persister.chain_sync_monitor_persistences.lock().unwrap().clone();
1074-
for (funding_outpoint, update_ids) in persistences {
1075-
for update_id in update_ids {
1076-
nodes[0].chain_monitor.chain_monitor.channel_monitor_updated(funding_outpoint, update_id).unwrap();
1077-
}
1078-
}
1079-
}
1080-
1081-
expect_payment_sent(&nodes[0], payment_preimage, None, true, false);
1082-
}
1083-
1084-
#[test]
1085-
fn chainsync_pauses_events() {
1086-
do_chainsync_pauses_events(false);
1087-
do_chainsync_pauses_events(true);
1088-
}
1089-
10901008
#[test]
10911009
#[cfg(feature = "std")]
10921010
fn update_during_chainsync_poisons_channel() {
@@ -1109,3 +1027,4 @@ mod tests {
11091027
}).is_err());
11101028
}
11111029
}
1030+

lightning/src/ln/payment_tests.rs

+18-28
Original file line numberDiff line numberDiff line change
@@ -1030,16 +1030,15 @@ fn test_completed_payment_not_retryable_on_reload() {
10301030
do_test_completed_payment_not_retryable_on_reload(false);
10311031
}
10321032

1033-
1034-
fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool, confirm_commitment_tx: bool, payment_timeout: bool) {
1033+
fn do_test_dup_htlc_onchain_doesnt_fail_on_reload(persist_manager_post_event: bool, confirm_commitment_tx: bool, payment_timeout: bool) {
10351034
// When a Channel is closed, any outbound HTLCs which were relayed through it are simply
1036-
// dropped when the Channel is. From there, the ChannelManager relies on the ChannelMonitor
1037-
// having a copy of the relevant fail-/claim-back data and processes the HTLC fail/claim when
1038-
// the ChannelMonitor tells it to.
1035+
// dropped. From there, the ChannelManager relies on the ChannelMonitor having a copy of the
1036+
// relevant fail-/claim-back data and processes the HTLC fail/claim when the ChannelMonitor tells
1037+
// it to.
10391038
//
1040-
// If, due to an on-chain event, an HTLC is failed/claimed, we should avoid providing the
1041-
// ChannelManager the HTLC event until after the monitor is re-persisted. This should prevent a
1042-
// duplicate HTLC fail/claim (e.g. via a PaymentPathFailed event).
1039+
// If, due to an on-chain event, an HTLC is failed/claimed, we provide the
1040+
// ChannelManager with the HTLC event without waiting for ChannelMonitor persistence.
1041+
// This might generate duplicate HTLC fail/claim (e.g. via a PaymentPathFailed event) on reload.
10431042
let chanmon_cfgs = create_chanmon_cfgs(2);
10441043
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
10451044
let persister;
@@ -1113,13 +1112,10 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool, co
11131112
}
11141113

11151114
let funding_txo = OutPoint { txid: funding_tx.txid(), index: 0 };
1116-
let mon_updates: Vec<_> = chanmon_cfgs[0].persister.chain_sync_monitor_persistences.lock().unwrap()
1117-
.get_mut(&funding_txo).unwrap().drain().collect();
1118-
// If we are using chain::Confirm instead of chain::Listen, we will get the same update twice.
1119-
// If we're testing connection idempotency we may get substantially more.
1120-
assert!(mon_updates.len() >= 1);
1121-
assert!(nodes[0].chain_monitor.release_pending_monitor_events().is_empty());
1122-
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
1115+
1116+
// Note that we skip persisting ChannelMonitors. We should still be generating the payment sent
1117+
// event without ChannelMonitor persistence. If we reset to a previous state on reload, the block
1118+
// should be replayed and we'll regenerate the event.
11231119

11241120
// If we persist the ChannelManager here, we should get the PaymentSent event after
11251121
// deserialization.
@@ -1128,13 +1124,7 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool, co
11281124
chan_manager_serialized = nodes[0].node.encode();
11291125
}
11301126

1131-
// Now persist the ChannelMonitor and inform the ChainMonitor that we're done, generating the
1132-
// payment sent event.
1133-
chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
11341127
let chan_0_monitor_serialized = get_monitor!(nodes[0], chan_id).encode();
1135-
for update in mon_updates {
1136-
nodes[0].chain_monitor.chain_monitor.channel_monitor_updated(funding_txo, update).unwrap();
1137-
}
11381128
if payment_timeout {
11391129
expect_payment_failed!(nodes[0], payment_hash, false);
11401130
} else {
@@ -1168,13 +1158,13 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool, co
11681158
}
11691159

11701160
#[test]
1171-
fn test_dup_htlc_onchain_fails_on_reload() {
1172-
do_test_dup_htlc_onchain_fails_on_reload(true, true, true);
1173-
do_test_dup_htlc_onchain_fails_on_reload(true, true, false);
1174-
do_test_dup_htlc_onchain_fails_on_reload(true, false, false);
1175-
do_test_dup_htlc_onchain_fails_on_reload(false, true, true);
1176-
do_test_dup_htlc_onchain_fails_on_reload(false, true, false);
1177-
do_test_dup_htlc_onchain_fails_on_reload(false, false, false);
1161+
fn test_dup_htlc_onchain_doesnt_fail_on_reload() {
1162+
do_test_dup_htlc_onchain_doesnt_fail_on_reload(true, true, true);
1163+
do_test_dup_htlc_onchain_doesnt_fail_on_reload(true, true, false);
1164+
do_test_dup_htlc_onchain_doesnt_fail_on_reload(true, false, false);
1165+
do_test_dup_htlc_onchain_doesnt_fail_on_reload(false, true, true);
1166+
do_test_dup_htlc_onchain_doesnt_fail_on_reload(false, true, false);
1167+
do_test_dup_htlc_onchain_doesnt_fail_on_reload(false, false, false);
11781168
}
11791169

11801170
#[test]

0 commit comments

Comments
 (0)