diff --git a/htlcswitch/hop/iterator.go b/htlcswitch/hop/iterator.go index c1073b1da..c72d6c0a4 100644 --- a/htlcswitch/hop/iterator.go +++ b/htlcswitch/hop/iterator.go @@ -363,7 +363,14 @@ func (p *OnionProcessor) DecodeHopIterators(id []byte, if replays.Contains(uint16(i)) { log.Errorf("unable to process onion packet: %v", sphinx.ErrReplayedPacket) - resp.FailCode = lnwire.CodeTemporaryChannelFailure + + // We set FailCode to CodeInvalidOnionVersion even + // though the ephemeral key isn't the problem. We need + // to set the BADONION bit since we're sending back a + // malformed packet, but as there isn't a specific + // failure code for replays, we reuse one of the + // failure codes that has BADONION. + resp.FailCode = lnwire.CodeInvalidOnionVersion continue } diff --git a/itest/lnd_misc_test.go b/itest/lnd_misc_test.go index bd71fa842..62a568e29 100644 --- a/itest/lnd_misc_test.go +++ b/itest/lnd_misc_test.go @@ -219,7 +219,7 @@ func testSphinxReplayPersistence(ht *lntest.HarnessTest) { // Assert that Fred receives the expected failure after Carol sent a // duplicate packet that fails due to sphinx replay detection. ht.AssertPaymentStatusFromStream(payStream, lnrpc.Payment_FAILED) - ht.AssertLastHTLCError(fred, lnrpc.Failure_INVALID_ONION_KEY) + ht.AssertLastHTLCError(fred, lnrpc.Failure_INVALID_ONION_VERSION) // Since the payment failed, the balance should still be left // unaltered.