diff --git a/contractcourt/htlc_timeout_resolver.go b/contractcourt/htlc_timeout_resolver.go index 670da607d..1c5620fc6 100644 --- a/contractcourt/htlc_timeout_resolver.go +++ b/contractcourt/htlc_timeout_resolver.go @@ -461,19 +461,23 @@ func (h *htlcTimeoutResolver) Resolve( return h.claimCleanUp(commitSpend) } - log.Infof("%T(%v): resolving htlc with incoming fail msg, fully "+ - "confirmed", h, h.htlcResolution.ClaimOutpoint) - // At this point, the second-level transaction is sufficiently // confirmed, or a transaction directly spending the output is. // Therefore, we can now send back our clean up message, failing the // HTLC on the incoming link. + // + // NOTE: This can be called twice if the outgoing resolver restarts + // before the second-stage timeout transaction is confirmed. + log.Infof("%T(%v): resolving htlc with incoming fail msg, "+ + "fully confirmed", h, h.htlcResolution.ClaimOutpoint) + failureMsg := &lnwire.FailPermanentChannelFailure{} - if err := h.DeliverResolutionMsg(ResolutionMsg{ + err = h.DeliverResolutionMsg(ResolutionMsg{ SourceChan: h.ShortChanID, HtlcIndex: h.htlc.HtlcIndex, Failure: failureMsg, - }); err != nil { + }) + if err != nil { return nil, err } diff --git a/htlcswitch/switch.go b/htlcswitch/switch.go index 10e4d37bf..cbc2a16da 100644 --- a/htlcswitch/switch.go +++ b/htlcswitch/switch.go @@ -1632,7 +1632,7 @@ out: defer s.wg.Done() if err := s.FlushForwardingEvents(); err != nil { - log.Errorf("unable to flush "+ + log.Errorf("Unable to flush "+ "forwarding events: %v", err) } }()