mirror of
https://github.com/ACINQ/eclair.git
synced 2024-11-20 10:39:19 +01:00
Reject payments for expired invoices (#1057)
* Reject payments for expired invoices
This commit is contained in:
parent
32145e8d6a
commit
20ea9d0e1d
@ -39,6 +39,7 @@ trait PaymentsDb {
|
||||
|
||||
def getPaymentRequest(paymentHash: ByteVector32): Option[PaymentRequest]
|
||||
|
||||
// returns non paid payment request
|
||||
def getPendingPaymentRequestAndPreimage(paymentHash: ByteVector32): Option[(ByteVector32, PaymentRequest)]
|
||||
|
||||
def listPaymentRequests(from: Long, to: Long): Seq[PaymentRequest]
|
||||
|
@ -65,6 +65,8 @@ class LocalPaymentHandler(nodeParams: NodeParams) extends Actor with ActorLoggin
|
||||
// it must not be greater than two times the requested amount.
|
||||
// see https://github.com/lightningnetwork/lightning-rfc/blob/master/04-onion-routing.md#failure-messages
|
||||
paymentRequest.amount match {
|
||||
case _ if paymentRequest.isExpired =>
|
||||
sender ! CMD_FAIL_HTLC(htlc.id, Right(IncorrectOrUnknownPaymentDetails(htlc.amountMsat)), commit = true)
|
||||
case _ if htlc.cltvExpiry < minFinalExpiry =>
|
||||
sender ! CMD_FAIL_HTLC(htlc.id, Right(FinalExpiryTooSoon), commit = true)
|
||||
case Some(amount) if MilliSatoshi(htlc.amountMsat) < amount =>
|
||||
|
@ -23,7 +23,8 @@ import fr.acinq.eclair.payment.PaymentRequest._
|
||||
import scodec.Codec
|
||||
import scodec.bits.{BitVector, ByteOrdering, ByteVector}
|
||||
import scodec.codecs.{list, ubyte}
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import scala.compat.Platform
|
||||
import scala.util.Try
|
||||
|
||||
/**
|
||||
@ -76,6 +77,11 @@ case class PaymentRequest(prefix: String, amount: Option[MilliSatoshi], timestam
|
||||
case cltvExpiry: PaymentRequest.MinFinalCltvExpiry => cltvExpiry.toLong
|
||||
}
|
||||
|
||||
def isExpired: Boolean = expiry match {
|
||||
case Some(expiryTime) => timestamp + expiryTime <= Platform.currentTime.milliseconds.toSeconds
|
||||
case None => timestamp + DEFAULT_EXPIRY_SECONDS <= Platform.currentTime.milliseconds.toSeconds
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the hash of this payment request
|
||||
@ -104,6 +110,8 @@ case class PaymentRequest(prefix: String, amount: Option[MilliSatoshi], timestam
|
||||
|
||||
object PaymentRequest {
|
||||
|
||||
val DEFAULT_EXPIRY_SECONDS = 3600
|
||||
|
||||
val prefixes = Map(
|
||||
Block.RegtestGenesisBlock.hash -> "lnbcrt",
|
||||
Block.TestnetGenesisBlock.hash -> "lntb",
|
||||
|
@ -52,6 +52,7 @@ class PaymentHandlerSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
|
||||
val pr = sender.expectMsgType[PaymentRequest]
|
||||
assert(nodeParams.db.payments.getIncomingPayment(pr.paymentHash).isEmpty)
|
||||
assert(nodeParams.db.payments.getPendingPaymentRequestAndPreimage(pr.paymentHash).isDefined)
|
||||
assert(!nodeParams.db.payments.getPendingPaymentRequestAndPreimage(pr.paymentHash).get._2.isExpired)
|
||||
|
||||
val add = UpdateAddHtlc(ByteVector32(ByteVector.fill(32)(1)), 0, amountMsat.amount, pr.paymentHash, expiry, ByteVector.empty)
|
||||
sender.send(handler, add)
|
||||
@ -149,4 +150,24 @@ class PaymentHandlerSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
|
||||
sender.send(handler, ReceivePayment(Some(MilliSatoshi(42000)), "1 coffee without routing info"))
|
||||
assert(sender.expectMsgType[PaymentRequest].routingInfo === Nil)
|
||||
}
|
||||
|
||||
test("LocalPaymentHandler should reject incoming payments if the payment request is expired") {
|
||||
val nodeParams = Alice.nodeParams
|
||||
val handler = TestActorRef[LocalPaymentHandler](LocalPaymentHandler.props(nodeParams))
|
||||
val sender = TestProbe()
|
||||
val eventListener = TestProbe()
|
||||
system.eventStream.subscribe(eventListener.ref, classOf[PaymentReceived])
|
||||
|
||||
val amountMsat = MilliSatoshi(42000)
|
||||
val expiry = Globals.blockCount.get() + 12
|
||||
|
||||
sender.send(handler, ReceivePayment(Some(amountMsat), "some desc", expirySeconds_opt = Some(0)))
|
||||
val pr = sender.expectMsgType[PaymentRequest]
|
||||
|
||||
val add = UpdateAddHtlc(ByteVector32(ByteVector.fill(32)(1)), 0, amountMsat.amount, pr.paymentHash, expiry, ByteVector.empty)
|
||||
sender.send(handler, add)
|
||||
|
||||
sender.expectMsgType[CMD_FAIL_HTLC]
|
||||
assert(nodeParams.db.payments.getIncomingPayment(pr.paymentHash).isEmpty)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user