From 6364ae33504f043b398f8444182545352596fa5c Mon Sep 17 00:00:00 2001 From: Anton Kumaigorodski Date: Wed, 10 Mar 2021 10:05:24 +0200 Subject: [PATCH] Reject trampoline payments with expired outgoing cltv (#1727) When we receive a trampoline payment asking us to relay with an expiry that is already below the current chain height, we know that this payment will fail when it reaches the next trampoline node. Instead of waiting for the next trampoline node to reject it, we reject it immediately. --- .../fr/acinq/eclair/payment/relay/NodeRelay.scala | 2 ++ .../eclair/payment/relay/NodeRelayerSpec.scala | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/relay/NodeRelay.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/relay/NodeRelay.scala index 4f7c8f8f3f..1239d28100 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/relay/NodeRelay.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/relay/NodeRelay.scala @@ -89,6 +89,8 @@ object NodeRelay { Some(TrampolineFeeInsufficient) } else if (upstream.expiryIn - payloadOut.outgoingCltv < nodeParams.expiryDelta) { Some(TrampolineExpiryTooSoon) + } else if (payloadOut.outgoingCltv <= CltvExpiry(nodeParams.currentBlockHeight)) { + Some(TrampolineExpiryTooSoon) } else { None } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/payment/relay/NodeRelayerSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/payment/relay/NodeRelayerSpec.scala index 3a7591764f..f397486e5b 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/payment/relay/NodeRelayerSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/payment/relay/NodeRelayerSpec.scala @@ -256,6 +256,21 @@ class NodeRelayerSpec extends ScalaTestWithActorTestKit(ConfigFactory.load("appl register.expectNoMessage(100 millis) } + test("fail to relay when final expiry is below chain height") { f => + import f._ + + val expiryIn = CltvExpiry(500000) + val expiryOut = CltvExpiry(300000) // not ok (chain heigh = 400000) + val p = createValidIncomingPacket(2000000 msat, 2000000 msat, expiryIn, 1000000 msat, expiryOut) + nodeRelayer ! NodeRelay.Relay(p) + + val fwd = register.expectMessageType[Register.Forward[CMD_FAIL_HTLC]] + assert(fwd.channelId === p.add.channelId) + assert(fwd.message === CMD_FAIL_HTLC(p.add.id, Right(TrampolineExpiryTooSoon), commit = true)) + + register.expectNoMessage(100 millis) + } + test("fail to relay when expiry is too soon (multi-part)") { f => import f._