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._