Skip to content

Commit a9534fe

Browse files
authored
Merge pull request #2059 from wpaulino/broadcast-missing-anchors-event
Queue BackgroundEvent to force close channels upon ChannelManager::read
2 parents 723c1a6 + 9fe4750 commit a9534fe

File tree

10 files changed

+161
-114
lines changed

10 files changed

+161
-114
lines changed

lightning-persister/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ mod tests {
141141
use bitcoin::{Txid, TxMerkleNode};
142142
use lightning::chain::ChannelMonitorUpdateStatus;
143143
use lightning::chain::chainmonitor::Persist;
144+
use lightning::chain::channelmonitor::CLOSED_CHANNEL_UPDATE_ID;
144145
use lightning::chain::transaction::OutPoint;
145146
use lightning::{check_closed_broadcast, check_closed_event, check_added_monitors};
146147
use lightning::events::{ClosureReason, MessageSendEventsProvider};
@@ -253,7 +254,7 @@ mod tests {
253254
check_added_monitors!(nodes[1], 1);
254255

255256
// Make sure everything is persisted as expected after close.
256-
check_persisted_data!(11);
257+
check_persisted_data!(CLOSED_CHANNEL_UPDATE_ID);
257258
}
258259

259260
// Test that if the persister's path to channel data is read-only, writing a

lightning/src/chain/channelmonitor.rs

+36-31
Original file line numberDiff line numberDiff line change
@@ -69,34 +69,36 @@ use crate::sync::{Mutex, LockTestExt};
6969
/// much smaller than a full [`ChannelMonitor`]. However, for large single commitment transaction
7070
/// updates (e.g. ones during which there are hundreds of HTLCs pending on the commitment
7171
/// transaction), a single update may reach upwards of 1 MiB in serialized size.
72-
#[cfg_attr(any(test, fuzzing, feature = "_test_utils"), derive(PartialEq, Eq))]
73-
#[derive(Clone)]
72+
#[derive(Clone, PartialEq, Eq)]
7473
#[must_use]
7574
pub struct ChannelMonitorUpdate {
7675
pub(crate) updates: Vec<ChannelMonitorUpdateStep>,
7776
/// The sequence number of this update. Updates *must* be replayed in-order according to this
7877
/// sequence number (and updates may panic if they are not). The update_id values are strictly
79-
/// increasing and increase by one for each new update, with one exception specified below.
78+
/// increasing and increase by one for each new update, with two exceptions specified below.
8079
///
8180
/// This sequence number is also used to track up to which points updates which returned
8281
/// [`ChannelMonitorUpdateStatus::InProgress`] have been applied to all copies of a given
8382
/// ChannelMonitor when ChannelManager::channel_monitor_updated is called.
8483
///
85-
/// The only instance where update_id values are not strictly increasing is the case where we
86-
/// allow post-force-close updates with a special update ID of [`CLOSED_CHANNEL_UPDATE_ID`]. See
87-
/// its docs for more details.
84+
/// The only instances we allow where update_id values are not strictly increasing have a
85+
/// special update ID of [`CLOSED_CHANNEL_UPDATE_ID`]. This update ID is used for updates that
86+
/// will force close the channel by broadcasting the latest commitment transaction or
87+
/// special post-force-close updates, like providing preimages necessary to claim outputs on the
88+
/// broadcast commitment transaction. See its docs for more details.
8889
///
8990
/// [`ChannelMonitorUpdateStatus::InProgress`]: super::ChannelMonitorUpdateStatus::InProgress
9091
pub update_id: u64,
9192
}
9293

93-
/// If:
94-
/// (1) a channel has been force closed and
95-
/// (2) we receive a preimage from a forward link that allows us to spend an HTLC output on
96-
/// this channel's (the backward link's) broadcasted commitment transaction
97-
/// then we allow the `ChannelManager` to send a `ChannelMonitorUpdate` with this update ID,
98-
/// with the update providing said payment preimage. No other update types are allowed after
99-
/// force-close.
94+
/// The update ID used for a [`ChannelMonitorUpdate`] that is either:
95+
///
96+
/// (1) attempting to force close the channel by broadcasting our latest commitment transaction or
97+
/// (2) providing a preimage (after the channel has been force closed) from a forward link that
98+
/// allows us to spend an HTLC output on this channel's (the backward link's) broadcasted
99+
/// commitment transaction.
100+
///
101+
/// No other [`ChannelMonitorUpdate`]s are allowed after force-close.
100102
pub const CLOSED_CHANNEL_UPDATE_ID: u64 = core::u64::MAX;
101103

102104
impl Writeable for ChannelMonitorUpdate {
@@ -488,8 +490,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
488490

489491
);
490492

491-
#[cfg_attr(any(test, fuzzing, feature = "_test_utils"), derive(PartialEq, Eq))]
492-
#[derive(Clone)]
493+
#[derive(Clone, PartialEq, Eq)]
493494
pub(crate) enum ChannelMonitorUpdateStep {
494495
LatestHolderCommitmentTXInfo {
495496
commitment_tx: HolderCommitmentTransaction,
@@ -1201,17 +1202,6 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
12011202
payment_hash, payment_preimage, broadcaster, fee_estimator, logger)
12021203
}
12031204

1204-
pub(crate) fn broadcast_latest_holder_commitment_txn<B: Deref, L: Deref>(
1205-
&self,
1206-
broadcaster: &B,
1207-
logger: &L,
1208-
) where
1209-
B::Target: BroadcasterInterface,
1210-
L::Target: Logger,
1211-
{
1212-
self.inner.lock().unwrap().broadcast_latest_holder_commitment_txn(broadcaster, logger);
1213-
}
1214-
12151205
/// Updates a ChannelMonitor on the basis of some new information provided by the Channel
12161206
/// itself.
12171207
///
@@ -2265,14 +2255,22 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
22652255
{
22662256
log_info!(logger, "Applying update to monitor {}, bringing update_id from {} to {} with {} changes.",
22672257
log_funding_info!(self), self.latest_update_id, updates.update_id, updates.updates.len());
2268-
// ChannelMonitor updates may be applied after force close if we receive a
2269-
// preimage for a broadcasted commitment transaction HTLC output that we'd
2270-
// like to claim on-chain. If this is the case, we no longer have guaranteed
2271-
// access to the monitor's update ID, so we use a sentinel value instead.
2258+
// ChannelMonitor updates may be applied after force close if we receive a preimage for a
2259+
// broadcasted commitment transaction HTLC output that we'd like to claim on-chain. If this
2260+
// is the case, we no longer have guaranteed access to the monitor's update ID, so we use a
2261+
// sentinel value instead.
2262+
//
2263+
// The `ChannelManager` may also queue redundant `ChannelForceClosed` updates if it still
2264+
// thinks the channel needs to have its commitment transaction broadcast, so we'll allow
2265+
// them as well.
22722266
if updates.update_id == CLOSED_CHANNEL_UPDATE_ID {
22732267
assert_eq!(updates.updates.len(), 1);
22742268
match updates.updates[0] {
2275-
ChannelMonitorUpdateStep::PaymentPreimage { .. } => {},
2269+
ChannelMonitorUpdateStep::ChannelForceClosed { .. } => {},
2270+
// We should have already seen a `ChannelForceClosed` update if we're trying to
2271+
// provide a preimage at this point.
2272+
ChannelMonitorUpdateStep::PaymentPreimage { .. } =>
2273+
debug_assert_eq!(self.latest_update_id, CLOSED_CHANNEL_UPDATE_ID),
22762274
_ => {
22772275
log_error!(logger, "Attempted to apply post-force-close ChannelMonitorUpdate of type {}", updates.updates[0].variant_name());
22782276
panic!("Attempted to apply post-force-close ChannelMonitorUpdate that wasn't providing a payment preimage");
@@ -2364,6 +2362,13 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
23642362
},
23652363
}
23662364
}
2365+
2366+
// If the updates succeeded and we were in an already closed channel state, then there's no
2367+
// need to refuse any updates we expect to receive afer seeing a confirmed commitment.
2368+
if ret.is_ok() && updates.update_id == CLOSED_CHANNEL_UPDATE_ID && self.latest_update_id == updates.update_id {
2369+
return Ok(());
2370+
}
2371+
23672372
self.latest_update_id = updates.update_id;
23682373

23692374
if ret.is_ok() && self.funding_spend_seen {

lightning/src/ln/channel.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use crate::ln::chan_utils;
3333
use crate::ln::onion_utils::HTLCFailReason;
3434
use crate::chain::BestBlock;
3535
use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBoundedFeeEstimator};
36-
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS};
36+
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS, CLOSED_CHANNEL_UPDATE_ID};
3737
use crate::chain::transaction::{OutPoint, TransactionData};
3838
use crate::chain::keysinterface::{WriteableEcdsaChannelSigner, EntropySource, ChannelSigner, SignerProvider, NodeSigner, Recipient};
3939
use crate::events::ClosureReason;
@@ -6081,7 +6081,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
60816081
// monitor update to the user, even if we return one).
60826082
// See test_duplicate_chan_id and test_pre_lockin_no_chan_closed_update for more.
60836083
if self.channel_state & (ChannelState::FundingSent as u32 | ChannelState::ChannelReady as u32 | ChannelState::ShutdownComplete as u32) != 0 {
6084-
self.latest_monitor_update_id += 1;
6084+
self.latest_monitor_update_id = CLOSED_CHANNEL_UPDATE_ID;
60856085
Some((funding_txo, ChannelMonitorUpdate {
60866086
update_id: self.latest_monitor_update_id,
60876087
updates: vec![ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast }],

lightning/src/ln/channelmanager.rs

+21-8
Original file line numberDiff line numberDiff line change
@@ -7354,6 +7354,7 @@ where
73547354
let mut id_to_peer = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
73557355
let mut short_to_chan_info = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
73567356
let mut channel_closures = Vec::new();
7357+
let mut pending_background_events = Vec::new();
73577358
for _ in 0..channel_count {
73587359
let mut channel: Channel<<SP::Target as SignerProvider>::Signer> = Channel::read(reader, (
73597360
&args.entropy_source, &args.signer_provider, best_block_height, &provided_channel_type_features(&args.default_config)
@@ -7383,9 +7384,11 @@ where
73837384
log_error!(args.logger, " The channel will be force-closed and the latest commitment transaction from the ChannelMonitor broadcast.");
73847385
log_error!(args.logger, " The ChannelMonitor for channel {} is at update_id {} but the ChannelManager is at update_id {}.",
73857386
log_bytes!(channel.channel_id()), monitor.get_latest_update_id(), channel.get_latest_monitor_update_id());
7386-
let (_, mut new_failed_htlcs) = channel.force_shutdown(true);
7387+
let (monitor_update, mut new_failed_htlcs) = channel.force_shutdown(true);
7388+
if let Some(monitor_update) = monitor_update {
7389+
pending_background_events.push(BackgroundEvent::ClosingMonitorUpdate(monitor_update));
7390+
}
73877391
failed_htlcs.append(&mut new_failed_htlcs);
7388-
monitor.broadcast_latest_holder_commitment_txn(&args.tx_broadcaster, &args.logger);
73897392
channel_closures.push(events::Event::ChannelClosed {
73907393
channel_id: channel.channel_id(),
73917394
user_channel_id: channel.get_user_id(),
@@ -7450,10 +7453,13 @@ where
74507453
}
74517454
}
74527455

7453-
for (funding_txo, monitor) in args.channel_monitors.iter_mut() {
7456+
for (funding_txo, _) in args.channel_monitors.iter() {
74547457
if !funding_txo_set.contains(funding_txo) {
7455-
log_info!(args.logger, "Broadcasting latest holder commitment transaction for closed channel {}", log_bytes!(funding_txo.to_channel_id()));
7456-
monitor.broadcast_latest_holder_commitment_txn(&args.tx_broadcaster, &args.logger);
7458+
let monitor_update = ChannelMonitorUpdate {
7459+
update_id: CLOSED_CHANNEL_UPDATE_ID,
7460+
updates: vec![ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast: true }],
7461+
};
7462+
pending_background_events.push(BackgroundEvent::ClosingMonitorUpdate((*funding_txo, monitor_update)));
74577463
}
74587464
}
74597465

@@ -7506,10 +7512,17 @@ where
75067512
}
75077513

75087514
let background_event_count: u64 = Readable::read(reader)?;
7509-
let mut pending_background_events_read: Vec<BackgroundEvent> = Vec::with_capacity(cmp::min(background_event_count as usize, MAX_ALLOC_SIZE/mem::size_of::<BackgroundEvent>()));
75107515
for _ in 0..background_event_count {
75117516
match <u8 as Readable>::read(reader)? {
7512-
0 => pending_background_events_read.push(BackgroundEvent::ClosingMonitorUpdate((Readable::read(reader)?, Readable::read(reader)?))),
7517+
0 => {
7518+
let (funding_txo, monitor_update): (OutPoint, ChannelMonitorUpdate) = (Readable::read(reader)?, Readable::read(reader)?);
7519+
if pending_background_events.iter().find(|e| {
7520+
let BackgroundEvent::ClosingMonitorUpdate((pending_funding_txo, pending_monitor_update)) = e;
7521+
*pending_funding_txo == funding_txo && *pending_monitor_update == monitor_update
7522+
}).is_none() {
7523+
pending_background_events.push(BackgroundEvent::ClosingMonitorUpdate((funding_txo, monitor_update)));
7524+
}
7525+
}
75137526
_ => return Err(DecodeError::InvalidValue),
75147527
}
75157528
}
@@ -7884,7 +7897,7 @@ where
78847897
per_peer_state: FairRwLock::new(per_peer_state),
78857898

78867899
pending_events: Mutex::new(pending_events_read),
7887-
pending_background_events: Mutex::new(pending_background_events_read),
7900+
pending_background_events: Mutex::new(pending_background_events),
78887901
total_consistency_lock: RwLock::new(()),
78897902
persistence_notifier: Notifier::new(),
78907903

lightning/src/ln/monitor_tests.rs

+26-27
Original file line numberDiff line numberDiff line change
@@ -1855,15 +1855,18 @@ fn test_anchors_aggregated_revoked_htlc_tx() {
18551855
let chan_a = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 20_000_000);
18561856
let chan_b = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 20_000_000);
18571857

1858+
// Serialize Bob with the initial state of both channels, which we'll use later.
1859+
let bob_serialized = nodes[1].node.encode();
1860+
18581861
// Route two payments for each channel from Alice to Bob to lock in the HTLCs.
18591862
let payment_a = route_payment(&nodes[0], &[&nodes[1]], 50_000_000);
18601863
let payment_b = route_payment(&nodes[0], &[&nodes[1]], 50_000_000);
18611864
let payment_c = route_payment(&nodes[0], &[&nodes[1]], 50_000_000);
18621865
let payment_d = route_payment(&nodes[0], &[&nodes[1]], 50_000_000);
18631866

1864-
// Serialize Bob with the HTLCs locked in. We'll restart Bob later on with the state at this
1865-
// point such that he broadcasts a revoked commitment transaction.
1866-
let bob_serialized = nodes[1].node.encode();
1867+
// Serialize Bob's monitors with the HTLCs locked in. We'll restart Bob later on with the state
1868+
// at this point such that he broadcasts a revoked commitment transaction with the HTLCs
1869+
// present.
18671870
let bob_serialized_monitor_a = get_monitor!(nodes[1], chan_a.2).encode();
18681871
let bob_serialized_monitor_b = get_monitor!(nodes[1], chan_b.2).encode();
18691872

@@ -1893,30 +1896,26 @@ fn test_anchors_aggregated_revoked_htlc_tx() {
18931896
}
18941897
}
18951898

1896-
// Bob force closes by broadcasting his revoked state for each channel.
1897-
nodes[1].node.force_close_broadcasting_latest_txn(&chan_a.2, &nodes[0].node.get_our_node_id()).unwrap();
1898-
check_added_monitors(&nodes[1], 1);
1899-
check_closed_broadcast(&nodes[1], 1, true);
1900-
check_closed_event!(&nodes[1], 1, ClosureReason::HolderForceClosed);
1901-
let revoked_commitment_a = {
1902-
let mut txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
1903-
assert_eq!(txn.len(), 1);
1904-
let revoked_commitment = txn.pop().unwrap();
1905-
assert_eq!(revoked_commitment.output.len(), 6); // 2 HTLC outputs + 1 to_self output + 1 to_remote output + 2 anchor outputs
1906-
check_spends!(revoked_commitment, chan_a.3);
1907-
revoked_commitment
1908-
};
1909-
nodes[1].node.force_close_broadcasting_latest_txn(&chan_b.2, &nodes[0].node.get_our_node_id()).unwrap();
1910-
check_added_monitors(&nodes[1], 1);
1911-
check_closed_broadcast(&nodes[1], 1, true);
1912-
check_closed_event!(&nodes[1], 1, ClosureReason::HolderForceClosed);
1913-
let revoked_commitment_b = {
1914-
let mut txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
1915-
assert_eq!(txn.len(), 1);
1916-
let revoked_commitment = txn.pop().unwrap();
1917-
assert_eq!(revoked_commitment.output.len(), 6); // 2 HTLC outputs + 1 to_self output + 1 to_remote output + 2 anchor outputs
1918-
check_spends!(revoked_commitment, chan_b.3);
1919-
revoked_commitment
1899+
// Bob force closes by restarting with the outdated state, prompting the ChannelMonitors to
1900+
// broadcast the latest commitment transaction known to them, which in our case is the one with
1901+
// the HTLCs still pending.
1902+
nodes[1].node.timer_tick_occurred();
1903+
check_added_monitors(&nodes[1], 2);
1904+
check_closed_event!(&nodes[1], 2, ClosureReason::OutdatedChannelManager);
1905+
let (revoked_commitment_a, revoked_commitment_b) = {
1906+
let txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
1907+
assert_eq!(txn.len(), 2);
1908+
assert_eq!(txn[0].output.len(), 6); // 2 HTLC outputs + 1 to_self output + 1 to_remote output + 2 anchor outputs
1909+
assert_eq!(txn[1].output.len(), 6); // 2 HTLC outputs + 1 to_self output + 1 to_remote output + 2 anchor outputs
1910+
if txn[0].input[0].previous_output.txid == chan_a.3.txid() {
1911+
check_spends!(&txn[0], &chan_a.3);
1912+
check_spends!(&txn[1], &chan_b.3);
1913+
(txn[0].clone(), txn[1].clone())
1914+
} else {
1915+
check_spends!(&txn[1], &chan_a.3);
1916+
check_spends!(&txn[0], &chan_b.3);
1917+
(txn[1].clone(), txn[0].clone())
1918+
}
19201919
};
19211920

19221921
// Bob should now receive two events to bump his revoked commitment transaction fees.

lightning/src/ln/payment_tests.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,15 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) {
335335
check_closed_event!(nodes[0], 1, ClosureReason::OutdatedChannelManager);
336336
assert!(nodes[0].node.list_channels().is_empty());
337337
assert!(nodes[0].node.has_pending_payments());
338-
let as_broadcasted_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
339-
assert_eq!(as_broadcasted_txn.len(), 1);
340-
assert_eq!(as_broadcasted_txn[0], as_commitment_tx);
338+
nodes[0].node.timer_tick_occurred();
339+
if !confirm_before_reload {
340+
let as_broadcasted_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
341+
assert_eq!(as_broadcasted_txn.len(), 1);
342+
assert_eq!(as_broadcasted_txn[0], as_commitment_tx);
343+
} else {
344+
assert!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().is_empty());
345+
}
346+
check_added_monitors!(nodes[0], 1);
341347

342348
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
343349
nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
@@ -500,9 +506,11 @@ fn do_test_completed_payment_not_retryable_on_reload(use_dust: bool) {
500506
// On reload, the ChannelManager should realize it is stale compared to the ChannelMonitor and
501507
// force-close the channel.
502508
check_closed_event!(nodes[0], 1, ClosureReason::OutdatedChannelManager);
509+
nodes[0].node.timer_tick_occurred();
503510
assert!(nodes[0].node.list_channels().is_empty());
504511
assert!(nodes[0].node.has_pending_payments());
505512
assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0).len(), 1);
513+
check_added_monitors!(nodes[0], 1);
506514

507515
nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap();
508516
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
@@ -2795,6 +2803,7 @@ fn do_no_missing_sent_on_midpoint_reload(persist_manager_with_payment: bool) {
27952803
if let Event::PaymentSent { payment_preimage, .. } = events[1] { assert_eq!(payment_preimage, our_payment_preimage); } else { panic!(); }
27962804
// Note that we don't get a PaymentPathSuccessful here as we leave the HTLC pending to avoid
27972805
// the double-claim that would otherwise appear at the end of this test.
2806+
nodes[0].node.timer_tick_occurred();
27982807
let as_broadcasted_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
27992808
assert_eq!(as_broadcasted_txn.len(), 1);
28002809

0 commit comments

Comments
 (0)