Skip to content

Commit e6966ce

Browse files
committed
Do not broadcast commitment txn on Permanent mon update failure
See doc updates for more info on the edge case this prevents, and there isn't really a strong reason why we would need to broadcast the latest state immediately. Specifically, in the case of HTLC claims (the most important reason to ensure we have state on chain if it cannot be persisted), we will still force-close if there are HTLCs which need claiming and are going to expire. Surprisingly, there were no tests which failed as a result of this change, but a new one has been added.
1 parent 7aa2cac commit e6966ce

File tree

3 files changed

+71
-52
lines changed

3 files changed

+71
-52
lines changed

lightning/src/chain/channelmonitor.rs

+59-42
Original file line numberDiff line numberDiff line change
@@ -123,56 +123,67 @@ pub enum ChannelMonitorUpdateErr {
123123
///
124124
/// Such a failure will "freeze" a channel, preventing us from revoking old states or
125125
/// submitting new commitment transactions to the counterparty. Once the update(s) which failed
126-
/// have been successfully applied, ChannelManager::channel_monitor_updated can be used to
126+
/// have been successfully applied, [`ChannelManager::channel_monitor_updated`] can be used to
127127
/// restore the channel to an operational state.
128128
///
129-
/// Note that a given ChannelManager will *never* re-generate a given ChannelMonitorUpdate. If
130-
/// you return a TemporaryFailure you must ensure that it is written to disk safely before
131-
/// writing out the latest ChannelManager state.
129+
/// Note that a given [`ChannelManager`] will *never* re-generate a [`ChannelMonitorUpdate`].
130+
/// If you return this error you must ensure that it is written to disk safely before writing
131+
/// the latest [`ChannelManager`] state, or you should return [`PermanentFailure`] instead.
132132
///
133-
/// Even when a channel has been "frozen" updates to the ChannelMonitor can continue to occur
134-
/// (eg if an inbound HTLC which we forwarded was claimed upstream resulting in us attempting
135-
/// to claim it on this channel) and those updates must be applied wherever they can be. At
136-
/// least one such updated ChannelMonitor must be persisted otherwise PermanentFailure should
137-
/// be returned to get things on-chain ASAP using only the in-memory copy. Obviously updates to
138-
/// the channel which would invalidate previous ChannelMonitors are not made when a channel has
139-
/// been "frozen".
133+
/// Even when a channel has been "frozen" updates to the [`ChannelMonitor`] can continue to
134+
/// occur (e.g. if an inbound HTLC which we forwarded was claimed upstream resulting in us
135+
/// attempting to claim it on this channel) and those updates must still be persisted.
140136
///
141-
/// Note that even if updates made after TemporaryFailure succeed you must still call
142-
/// channel_monitor_updated to ensure you have the latest monitor and re-enable normal channel
143-
/// operation.
144-
///
145-
/// Note that the update being processed here will not be replayed for you when you call
146-
/// ChannelManager::channel_monitor_updated, so you must store the update itself along
147-
/// with the persisted ChannelMonitor on your own local disk prior to returning a
148-
/// TemporaryFailure. You may, of course, employ a journaling approach, storing only the
149-
/// ChannelMonitorUpdate on disk without updating the monitor itself, replaying the journal at
150-
/// reload-time.
137+
/// No updates to the channel will be made which could invalidate other [`ChannelMonitor`]s
138+
/// until [`ChannelManager::channel_monitor_updated`] is called, even if you return no error on
139+
/// a later monitor update for the same channel.
151140
///
152141
/// For deployments where a copy of ChannelMonitors and other local state are backed up in a
153142
/// remote location (with local copies persisted immediately), it is anticipated that all
154143
/// updates will return TemporaryFailure until the remote copies could be updated.
144+
///
145+
/// [`PermanentFailure`]: ChannelMonitorUpdateErr::PermanentFailure
146+
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
147+
/// [`ChannelManager::channel_monitor_updated`]: crate::ln::channelmanager::ChannelManager::channel_monitor_updated
155148
TemporaryFailure,
156-
/// Used to indicate no further channel monitor updates will be allowed (eg we've moved on to a
157-
/// different watchtower and cannot update with all watchtowers that were previously informed
158-
/// of this channel).
149+
/// Used to indicate no further channel monitor updates will be allowed (likely a disk failure
150+
/// or, e.g. we've moved on to a different watchtower and cannot update with all watchtowers
151+
/// that were previously informed of this channel).
152+
///
153+
/// When this is returned [`ChannelManager`] will force-close the channel but *not* broadcast
154+
/// our current commitment transaction. This avoids a dangerous case where a local disk failure
155+
/// (e.g. the Linux-default remounting of the disk as read-only) causes [`PermanentFailure`]s
156+
/// for all monitor updates. If we were to broadcast our latest commitment transaction and then
157+
/// restart, we could end up reading a previous [`ChannelMonitor`] and [`ChannelManager`],
158+
/// revoking our now-broadcasted state before seeing it confirm and losing all our funds.
159+
///
160+
/// Note that this is somewhat of a tradeoff - if the disk is really gone and we may have lost
161+
/// the data permanently, we really should broadcast immediately. If the data can be recovered
162+
/// with manual intervention, we'd rather close the channel, rejecting future updates to it,
163+
/// and broadcast the latest state only if we have HTLCs to claim which are timing out (which
164+
/// we do as long as blocks are connected).
159165
///
160-
/// At reception of this error, ChannelManager will force-close the channel and return at
161-
/// least a final ChannelMonitorUpdate::ChannelForceClosed which must be delivered to at
162-
/// least one ChannelMonitor copy. Revocation secret MUST NOT be released and offchain channel
163-
/// update must be rejected.
166+
/// In order to broadcast the latest local commitment transaction, you'll need to call
167+
/// [`ChannelMonitor::get_latest_holder_commitment_txn`] once you've safely ensured no further
168+
/// off-chain updates to the channel can occur.
164169
///
165-
/// This failure may also signal a failure to update the local persisted copy of one of
166-
/// the channel monitor instance.
170+
/// Note that at least one final [`ChannelMonitorUpdate`] may still be provided, which must
171+
/// still be processed by a running [`ChannelMonitor`]. This final update will mark the
172+
/// [`ChannelMonitor`] as finalized, ensuring no further updates (e.g. revocation of the latest
173+
/// commitment transaction) are allowed.
167174
///
168-
/// Note that even when you fail a holder commitment transaction update, you must store the
169-
/// update to ensure you can claim from it in case of a duplicate copy of this ChannelMonitor
170-
/// broadcasts it (e.g distributed channel-monitor deployment)
175+
/// Note that even if you return a [`PermanentFailure`] due to unavailability of secondary
176+
/// [`ChannelMonitor`] copies, you should still make an attempt to store the update where
177+
/// possible to ensure you can claim HTLC outputs on the latest commitment transaction
178+
/// broadcasted later.
171179
///
172180
/// In case of distributed watchtowers deployment, the new version must be written to disk, as
173181
/// state may have been stored but rejected due to a block forcing a commitment broadcast. This
174182
/// storage is used to claim outputs of rejected state confirmed onchain by another watchtower,
175183
/// lagging behind on block processing.
184+
///
185+
/// [`PermanentFailure`]: ChannelMonitorUpdateErr::PermanentFailure
186+
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
176187
PermanentFailure,
177188
}
178189

@@ -1203,14 +1214,18 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
12031214
}
12041215

12051216
/// Used by ChannelManager deserialization to broadcast the latest holder state if its copy of
1206-
/// the Channel was out-of-date. You may use it to get a broadcastable holder toxic tx in case of
1207-
/// fallen-behind, i.e when receiving a channel_reestablish with a proof that our counterparty side knows
1208-
/// a higher revocation secret than the holder commitment number we are aware of. Broadcasting these
1209-
/// transactions are UNSAFE, as they allow counterparty side to punish you. Nevertheless you may want to
1210-
/// broadcast them if counterparty don't close channel with his higher commitment transaction after a
1211-
/// substantial amount of time (a month or even a year) to get back funds. Best may be to contact
1212-
/// out-of-band the other node operator to coordinate with him if option is available to you.
1213-
/// In any-case, choice is up to the user.
1217+
/// the Channel was out-of-date.
1218+
///
1219+
/// You may also use this to broadcast the latest local commitment transaction, either because
1220+
/// a monitor update failed with [`ChannelMonitorUpdateErr::PermanentFailure`] or because we've
1221+
/// fallen behind (i.e we've received proof that our counterparty side knows a revocation
1222+
/// secret we gave them that they shouldn't know).
1223+
///
1224+
/// Broadcasting these transactions in the second case is UNSAFE, as they allow counterparty
1225+
/// side to punish you. Nevertheless you may want to broadcast them if counterparty doesn't
1226+
/// close channel with their commitment transaction after a substantial amount of time. Best
1227+
/// may be to contact the other node operator out-of-band to coordinate other options available
1228+
/// to you. In any-case, the choice is up to you.
12141229
pub fn get_latest_holder_commitment_txn<L: Deref>(&self, logger: &L) -> Vec<Transaction>
12151230
where L::Target: Logger {
12161231
self.inner.lock().unwrap().get_latest_holder_commitment_txn(logger)
@@ -1833,7 +1848,9 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
18331848
if *should_broadcast {
18341849
self.broadcast_latest_holder_commitment_txn(broadcaster, logger);
18351850
} else if !self.holder_tx_signed {
1836-
log_error!(logger, "You have a toxic holder commitment transaction avaible in channel monitor, read comment in ChannelMonitor::get_latest_holder_commitment_txn to be informed of manual action to take");
1851+
log_error!(logger, "WARNING: You have a potentially-toxic holder commitment transaction avaible to broadcast");
1852+
log_error!(logger, " in channel monitor for channel {}!", log_bytes!(self.funding_info.0.to_channel_id()));
1853+
log_error!(logger, " Read the docs for ChannelMonitor::get_latest_holder_commitment_txn and take manual action!");
18371854
} else {
18381855
// If we generated a MonitorEvent::CommitmentTxConfirmed, the ChannelManager
18391856
// will still give us a ChannelForceClosed event with !should_broadcast, but we

lightning/src/ln/chanmon_update_fail_tests.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,23 @@ fn do_test_simple_monitor_permanent_update_fail(persister_fail: bool) {
7777
_ => panic!("Unexpected event"),
7878
};
7979

80+
assert!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().is_empty());
81+
8082
// TODO: Once we hit the chain with the failure transaction we should check that we get a
8183
// PaymentPathFailed event
8284

8385
assert_eq!(nodes[0].node.list_channels().len(), 0);
8486
check_closed_event!(nodes[0], 1, ClosureReason::ProcessingError { err: "ChannelMonitor storage failure".to_string() });
8587
}
8688

89+
#[test]
90+
fn test_simple_monitor_permanent_update_fail() {
91+
do_test_simple_monitor_permanent_update_fail(false);
92+
93+
// Test behavior when the persister returns a PermanentFailure.
94+
do_test_simple_monitor_permanent_update_fail(true);
95+
}
96+
8797
#[test]
8898
fn test_monitor_and_persister_update_fail() {
8999
// Test that if both updating the `ChannelMonitor` and persisting the updated
@@ -158,14 +168,6 @@ fn test_monitor_and_persister_update_fail() {
158168
assert_eq!(events.len(), 1);
159169
}
160170

161-
#[test]
162-
fn test_simple_monitor_permanent_update_fail() {
163-
do_test_simple_monitor_permanent_update_fail(false);
164-
165-
// Test behavior when the persister returns a PermanentFailure.
166-
do_test_simple_monitor_permanent_update_fail(true);
167-
}
168-
169171
// If persister_fail is true, we have the persister return a TemporaryFailure instead of the
170172
// higher-level ChainMonitor.
171173
fn do_test_simple_monitor_temporary_update_fail(disconnect: bool, persister_fail: bool) {

lightning/src/ln/channelmanager.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,7 @@ macro_rules! handle_monitor_err {
10141014
// given up the preimage yet, so might as well just wait until the payment is
10151015
// retried, avoiding the on-chain fees.
10161016
let res: Result<(), _> = Err(MsgHandleErrInternal::from_finish_shutdown("ChannelMonitor storage failure".to_owned(), *$chan_id,
1017-
$chan.force_shutdown(true), $self.get_channel_update_for_broadcast(&$chan).ok() ));
1017+
$chan.force_shutdown(false), $self.get_channel_update_for_broadcast(&$chan).ok() ));
10181018
(res, true)
10191019
},
10201020
ChannelMonitorUpdateErr::TemporaryFailure => {
@@ -3499,7 +3499,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
34993499
// We do not do a force-close here as that would generate a monitor update for
35003500
// a monitor that we didn't manage to store (and that we don't care about - we
35013501
// don't respond with the funding_signed so the channel can never go on chain).
3502-
let (_monitor_update, failed_htlcs) = chan.force_shutdown(true);
3502+
let (_monitor_update, failed_htlcs) = chan.force_shutdown(false);
35033503
assert!(failed_htlcs.is_empty());
35043504
return Err(MsgHandleErrInternal::send_err_msg_no_close("ChannelMonitor storage failure".to_owned(), funding_msg.channel_id));
35053505
},

0 commit comments

Comments
 (0)