Skip to content

Commit 8eb7146

Browse files
Update monitor with preimage after channel close
If the channel is hitting the chain right as we receive a preimage, previous to this commit the relevant ChannelMonitor would never learn of this preimage.
1 parent c920493 commit 8eb7146

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,32 @@ pub struct ChannelMonitorUpdate {
6464
pub(crate) updates: Vec<ChannelMonitorUpdateStep>,
6565
/// The sequence number of this update. Updates *must* be replayed in-order according to this
6666
/// sequence number (and updates may panic if they are not). The update_id values are strictly
67-
/// increasing and increase by one for each new update.
67+
/// increasing and increase by one for each new update, with one exception specified below.
6868
///
6969
/// This sequence number is also used to track up to which points updates which returned
7070
/// ChannelMonitorUpdateErr::TemporaryFailure have been applied to all copies of a given
7171
/// ChannelMonitor when ChannelManager::channel_monitor_updated is called.
72+
///
73+
/// The only instance where update_id values are not strictly increasing is the case where: (1)
74+
/// the channel has been force closed and (2) we receive a preimage from a forward link that
75+
/// allows us to spend an HTLC output on this channel's (the backward link's) broadcasted
76+
/// commitment transaction. In this case, we allow the `ChannelManager` to send a
77+
/// `ChannelMonitorUpdate` with an update_id of [`CLOSED_CHANNEL_UPDATE_ID`], with the update
78+
/// providing said payment preimage. No other update types are allowed after force-close.
79+
///
80+
/// [`CLOSED_CHANNEL_UPDATE_ID`]: constant.CLOSED_CHANNEL_UPDATE_ID.html
7281
pub update_id: u64,
7382
}
7483

84+
/// If:
85+
/// (1) a channel has been force closed and
86+
/// (2) we receive a preimage from a forward link that allows us to spend an HTLC output on
87+
/// this channel's (the backward link's) broadcasted commitment transaction
88+
/// then we allow the `ChannelManager` to send a `ChannelMonitorUpdate` with this update ID,
89+
/// with the update providing said payment preimage. No other update types are allowed after
90+
/// force-close.
91+
pub const CLOSED_CHANNEL_UPDATE_ID: u64 = std::u64::MAX;
92+
7593
impl Writeable for ChannelMonitorUpdate {
7694
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
7795
self.update_id.write(w)?;
@@ -1166,7 +1184,18 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
11661184
where B::Target: BroadcasterInterface,
11671185
L::Target: Logger,
11681186
{
1169-
if self.latest_update_id + 1 != updates.update_id {
1187+
// ChannelMonitor updates may be applied after force close if we receive a
1188+
// preimage for a broadcasted commitment transaction HTLC output that we'd
1189+
// like to claim on-chain. If this is the case, we no longer have guaranteed
1190+
// access to the monitor's update ID, so we use a sentinel value instead.
1191+
if updates.update_id == CLOSED_CHANNEL_UPDATE_ID {
1192+
match updates.updates[0] {
1193+
ChannelMonitorUpdateStep::PaymentPreimage { .. } => {},
1194+
_ => panic!("Attempted to apply post-force-close ChannelMonitorUpdate that wasn't providing a payment preimage"),
1195+
}
1196+
assert_eq!(updates.updates.len(), 1);
1197+
}
1198+
if updates.update_id != CLOSED_CHANNEL_UPDATE_ID && self.latest_update_id + 1 != updates.update_id {
11701199
panic!("Attempted to apply ChannelMonitorUpdates out of order, check the update_id before passing an update to update_monitor!");
11711200
}
11721201
for update in updates.updates.iter() {

lightning/src/ln/channelmanager.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use bitcoin::secp256k1;
3737
use chain;
3838
use chain::Watch;
3939
use chain::chaininterface::{BroadcasterInterface, FeeEstimator};
40-
use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateErr, HTLC_FAIL_BACK_BUFFER, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY, MonitorEvent};
40+
use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, ChannelMonitorUpdateErr, HTLC_FAIL_BACK_BUFFER, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY, MonitorEvent, CLOSED_CHANNEL_UPDATE_ID};
4141
use chain::transaction::{OutPoint, TransactionData};
4242
use ln::channel::{Channel, ChannelError};
4343
use ln::features::{InitFeatures, NodeFeatures};
@@ -2152,12 +2152,22 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
21522152
});
21532153
},
21542154
HTLCSource::PreviousHopData(hop_data) => {
2155+
let prev_outpoint = hop_data.outpoint;
21552156
if let Err((counterparty_node_id, err)) = match self.claim_funds_from_hop(&mut channel_state_lock, hop_data, payment_preimage) {
21562157
Ok(()) => Ok(()),
21572158
Err(None) => {
2158-
// TODO: There is probably a channel monitor somewhere that needs to
2159-
// learn the preimage as the channel already hit the chain and that's
2160-
// why it's missing.
2159+
let preimage_update = ChannelMonitorUpdate {
2160+
update_id: CLOSED_CHANNEL_UPDATE_ID,
2161+
updates: vec![ChannelMonitorUpdateStep::PaymentPreimage {
2162+
payment_preimage: payment_preimage.clone(),
2163+
}],
2164+
};
2165+
// We update the ChannelMonitor on the backward link, after
2166+
// receiving an offchain preimage event from the forward link (the
2167+
// event being update_fulfill_htlc).
2168+
if let Err(e) = self.chain_monitor.update_channel(prev_outpoint, preimage_update) {
2169+
log_error!(self.logger, "Critical error: failed to update channel monitor with preimage: {:?}", e);
2170+
}
21612171
Ok(())
21622172
},
21632173
Err(Some(res)) => Err(res),

0 commit comments

Comments
 (0)