Skip to content

Commit e008be3

Browse files
committed
Handle closed-chan HTLC claims in claim_funds_from_hop
Currently `claim_funds` does all HTLC claims in one `channel_state` lock, ensuring that we always make claims from channels which are open. It can thus avoid ever having to generate a `ChannelMonitorUpdate` containing a preimage for a closed channel, which we only do in `claim_funds_internal` (for forwarded payments). In the next commit we'll change the locking of `claim_funds_from_hop` so that `claim_funds` is no longer under a single lock but takes a lock for each claim. This allows us to be more flexible with locks going forward, and ultimately isn't a huge change - if our counterparty intends to force-close a channel, us choosing to ignore it by holding the `channel_state` lock for the duration of the claim isn't going to result in a commitment update, it will just result in the preimage already being in the `ChannelMonitor`.
1 parent 536751d commit e008be3

File tree

1 file changed

+23
-25
lines changed

1 file changed

+23
-25
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4303,6 +4303,29 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
43034303
},
43044304
}
43054305
} else {
4306+
let preimage_update = ChannelMonitorUpdate {
4307+
update_id: CLOSED_CHANNEL_UPDATE_ID,
4308+
updates: vec![ChannelMonitorUpdateStep::PaymentPreimage {
4309+
payment_preimage,
4310+
}],
4311+
};
4312+
// We update the ChannelMonitor on the backward link, after
4313+
// receiving an offchain preimage event from the forward link (the
4314+
// event being update_fulfill_htlc).
4315+
let update_res = self.chain_monitor.update_channel(prev_hop.outpoint, preimage_update);
4316+
if update_res != ChannelMonitorUpdateStatus::Completed {
4317+
// TODO: This needs to be handled somehow - if we receive a monitor update
4318+
// with a preimage we *must* somehow manage to propagate it to the upstream
4319+
// channel, or we must have an ability to receive the same event and try
4320+
// again on restart.
4321+
log_error!(self.logger, "Critical error: failed to update channel monitor with preimage {:?}: {:?}",
4322+
payment_preimage, update_res);
4323+
}
4324+
// Note that we do process the completion action here. This totally could be a
4325+
// duplicate claim, but we have no way of knowing without interrogating the
4326+
// `ChannelMonitor` we've provided the above update to. Instead, note that `Event`s are
4327+
// generally always allowed to be duplicative (and it's specifically noted in
4328+
// `PaymentForwarded`)..
43064329
self.handle_monitor_update_completion_actions(completion_action(None));
43074330
return ClaimFundsFromHop::PrevHopForceClosed
43084331
}
@@ -4396,31 +4419,6 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
43964419
}})
43974420
} else { None }
43984421
});
4399-
if let ClaimFundsFromHop::PrevHopForceClosed = res {
4400-
let preimage_update = ChannelMonitorUpdate {
4401-
update_id: CLOSED_CHANNEL_UPDATE_ID,
4402-
updates: vec![ChannelMonitorUpdateStep::PaymentPreimage {
4403-
payment_preimage: payment_preimage.clone(),
4404-
}],
4405-
};
4406-
// We update the ChannelMonitor on the backward link, after
4407-
// receiving an offchain preimage event from the forward link (the
4408-
// event being update_fulfill_htlc).
4409-
let update_res = self.chain_monitor.update_channel(prev_outpoint, preimage_update);
4410-
if update_res != ChannelMonitorUpdateStatus::Completed {
4411-
// TODO: This needs to be handled somehow - if we receive a monitor update
4412-
// with a preimage we *must* somehow manage to propagate it to the upstream
4413-
// channel, or we must have an ability to receive the same event and try
4414-
// again on restart.
4415-
log_error!(self.logger, "Critical error: failed to update channel monitor with preimage {:?}: {:?}",
4416-
payment_preimage, update_res);
4417-
}
4418-
// Note that we do *not* set `claimed_htlc` to false here. In fact, this
4419-
// totally could be a duplicate claim, but we have no way of knowing
4420-
// without interrogating the `ChannelMonitor` we've provided the above
4421-
// update to. Instead, we simply document in `PaymentForwarded` that this
4422-
// can happen.
4423-
}
44244422
mem::drop(channel_state_lock);
44254423
if let ClaimFundsFromHop::MonitorUpdateFail(pk, err, _) = res {
44264424
let result: Result<(), _> = Err(err);

0 commit comments

Comments
 (0)