From 04f576ee6e96b982046525059eca55da059a717b Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Fri, 25 May 2018 18:40:25 -0700 Subject: [PATCH] lnwallet: reject duplicate fails for the same HTLC --- lnwallet/channel.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/lnwallet/channel.go b/lnwallet/channel.go index c1b269d4..d5b86e30 100644 --- a/lnwallet/channel.go +++ b/lnwallet/channel.go @@ -4496,6 +4496,13 @@ func (lc *LightningChannel) FailHTLC(htlcIndex uint64, reason []byte, lc.ShortChanID()) } + // Now that we know the HTLC exists, we'll ensure that we haven't + // already attempted to fail the HTLC. + if lc.remoteUpdateLog.htlcHasModification(htlcIndex) { + return fmt.Errorf("HTLC with ID %d has already been failed", + htlcIndex) + } + pd := &PaymentDescriptor{ Amount: htlc.Amount, RHash: htlc.RHash, @@ -4510,6 +4517,11 @@ func (lc *LightningChannel) FailHTLC(htlcIndex uint64, reason []byte, lc.localUpdateLog.appendUpdate(pd) + // With the fail added to the remote log, we'll now mark the HTLC as + // modified to prevent ourselves from accidentally attempting a + // duplicate fail. + lc.remoteUpdateLog.markHtlcModified(htlcIndex) + return nil } @@ -4536,6 +4548,13 @@ func (lc *LightningChannel) MalformedFailHTLC(htlcIndex uint64, lc.ShortChanID()) } + // Now that we know the HTLC exists, we'll ensure that we haven't + // already attempted to fail the HTLC. + if lc.remoteUpdateLog.htlcHasModification(htlcIndex) { + return fmt.Errorf("HTLC with ID %d has already been failed", + htlcIndex) + } + pd := &PaymentDescriptor{ Amount: htlc.Amount, RHash: htlc.RHash, @@ -4549,6 +4568,11 @@ func (lc *LightningChannel) MalformedFailHTLC(htlcIndex uint64, lc.localUpdateLog.appendUpdate(pd) + // With the fail added to the remote log, we'll now mark the HTLC as + // modified to prevent ourselves from accidentally attempting a + // duplicate fail. + lc.remoteUpdateLog.markHtlcModified(htlcIndex) + return nil } @@ -4569,6 +4593,13 @@ func (lc *LightningChannel) ReceiveFailHTLC(htlcIndex uint64, reason []byte, lc.ShortChanID()) } + // Now that we know the HTLC exists, we'll ensure that they haven't + // already attempted to fail the HTLC. + if lc.localUpdateLog.htlcHasModification(htlcIndex) { + return fmt.Errorf("HTLC with ID %d has already been failed", + htlcIndex) + } + pd := &PaymentDescriptor{ Amount: htlc.Amount, RHash: htlc.RHash, @@ -4580,6 +4611,11 @@ func (lc *LightningChannel) ReceiveFailHTLC(htlcIndex uint64, reason []byte, lc.remoteUpdateLog.appendUpdate(pd) + // With the fail added to the remote log, we'll now mark the HTLC as + // modified to prevent ourselves from accidentally attempting a + // duplicate fail. + lc.localUpdateLog.markHtlcModified(htlcIndex) + return nil }