- return Ok(None);
- }
-
- let mut htlc_id = 0;
- let mut htlc_amount_msat = 0;
- for htlc in self.pending_htlcs.iter_mut() {
- if !htlc.outbound && htlc.payment_hash == payment_hash_calc {
- if htlc_id != 0 {
- panic!("Duplicate HTLC payment_hash, you probably re-used payment preimages, NEVER DO THIS!");
- }
- htlc_id = htlc.htlc_id;
- htlc_amount_msat += htlc.amount_msat;
- if htlc.state == HTLCState::Committed {
- htlc.state = HTLCState::LocalRemoved;
- htlc.local_removed_fulfilled = true;
- } else if htlc.state == HTLCState::RemoteAnnounced {
- panic!("Somehow forwarded HTLC prior to remote revocation!");
- } else if htlc.state == HTLCState::LocalRemoved || htlc.state == HTLCState::LocalRemovedAwaitingCommitment {
- return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", action: None});
- } else {
- panic!("Have an inbound HTLC when not awaiting remote revoke that had a garbage state");
- }
+ return Ok((None, Some(self.channel_monitor.clone())));
+ }
+
+ let htlc_id = {
+ let htlc = &mut self.pending_htlcs[pending_idx];
+ if htlc.state == HTLCState::Committed {
+ htlc.state = HTLCState::LocalRemoved;
+ htlc.local_removed_fulfilled = true;
+ } else if htlc.state == HTLCState::RemoteAnnounced || htlc.state == HTLCState::AwaitingRemoteRevokeToAnnounce || htlc.state == HTLCState::AwaitingAnnouncedRemoteRevoke {
+ // Theoretically we can hit this if we get the preimage on an HTLC prior to us
+ // having forwarded it to anyone. This implies that the sender is busted as someone
+ // else knows the preimage, but handling this case and implementing the logic to
+ // take their money would be a lot of (never-tested) code to handle a case that
+ // hopefully never happens. Instead, we make sure we get the preimage into the
+ // channel_monitor and pretend we didn't just see the preimage.
+ return Ok((None, Some(self.channel_monitor.clone())));
+ } else if htlc.state == HTLCState::LocalRemoved || htlc.state == HTLCState::LocalRemovedAwaitingCommitment {
+ return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", action: None});
+ } else {
+ panic!("Have an inbound HTLC when not awaiting remote revoke that had a garbage state");