From 61e71741861ed345a9a2ce53f0c4b458b7e30707 Mon Sep 17 00:00:00 2001 From: Andrea Date: Fri, 8 Feb 2019 11:16:48 +0100 Subject: [PATCH] Remove max-payment-fee in favor of router.search-max-fee-pct --- eclair-core/src/main/resources/reference.conf | 3 +-- .../main/scala/fr/acinq/eclair/NodeParams.scala | 2 -- .../main/scala/fr/acinq/eclair/api/Service.scala | 6 +++--- .../acinq/eclair/payment/PaymentLifecycle.scala | 16 ++-------------- .../scala/fr/acinq/eclair/TestConstants.scala | 2 -- .../eclair/payment/PaymentLifecycleSpec.scala | 4 ++-- .../scala/fr/acinq/eclair/gui/Handlers.scala | 2 +- 7 files changed, 9 insertions(+), 26 deletions(-) diff --git a/eclair-core/src/main/resources/reference.conf b/eclair-core/src/main/resources/reference.conf index fe1023ca7f..a2e0bf86a8 100644 --- a/eclair-core/src/main/resources/reference.conf +++ b/eclair-core/src/main/resources/reference.conf @@ -87,7 +87,6 @@ eclair { payment-handler = "local" payment-request-expiry = 1 hour // default expiry for payment requests generated by this node max-pending-payment-requests = 10000000 - max-payment-fee = 0.03 // max total fee for outgoing payments, in percentage: sending a payment will not be attempted if the cheapest route found is more expensive than that min-funding-satoshis = 100000 autoprobe-count = 0 // number of parallel tasks that send test payments to detect invalid channels @@ -102,6 +101,6 @@ eclair { search-max-length = 6 // route max length for the 'first pass' search-max-cltv = 1008 // max delay the route will have - one week search-fee-base-msat = 21000 // floor for the max fee of a route - search-max-fee-pct = 0.03 // a cap for the max fee payable by a route, in percentage related to the amount to be sent + search-max-fee-pct = 0.03 // a cap for the max fee payable by a route, in percentage related to the amount to be sent. This is not considered if fees < search-fee-base-msat } } \ No newline at end of file diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala b/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala index 8d767a9c54..c134cc56ad 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala @@ -77,7 +77,6 @@ case class NodeParams(keyManager: KeyManager, watcherType: WatcherType, paymentRequestExpiry: FiniteDuration, maxPendingPaymentRequests: Int, - maxPaymentFee: Double, minFundingSatoshis: Long, routerConf: RouterConf) { @@ -219,7 +218,6 @@ object NodeParams { watcherType = watcherType, paymentRequestExpiry = FiniteDuration(config.getDuration("payment-request-expiry").getSeconds, TimeUnit.SECONDS), maxPendingPaymentRequests = config.getInt("max-pending-payment-requests"), - maxPaymentFee = config.getDouble("max-payment-fee"), minFundingSatoshis = config.getLong("min-funding-satoshis"), routerConf = RouterConf( channelExcludeDuration = FiniteDuration(config.getDuration("router.channel-exclude-duration").getSeconds, TimeUnit.SECONDS), diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/api/Service.scala b/eclair-core/src/main/scala/fr/acinq/eclair/api/Service.scala index 638d05d8a4..e4b49a5b04 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/api/Service.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/api/Service.scala @@ -266,7 +266,7 @@ trait Service extends Logging { case JInt(amountMsat) :: JString(paymentHash) :: JString(nodeId) :: Nil => (Try(BinaryData(paymentHash)), Try(PublicKey(nodeId))) match { case (Success(ph), Success(pk)) => completeRpcFuture(req.id, (paymentInitiator ? - SendPayment(amountMsat.toLong, ph, pk, maxFeePct = nodeParams.maxPaymentFee)).mapTo[PaymentResult].map { + SendPayment(amountMsat.toLong, ph, pk)).mapTo[PaymentResult].map { case s: PaymentSucceeded => s case f: PaymentFailed => f.copy(failures = PaymentLifecycle.transformForUser(f.failures)) }) @@ -286,8 +286,8 @@ trait Service extends Logging { logger.debug(s"api call for sending payment with amount_msat=$amount_msat") // optional cltv expiry val sendPayment = pr.minFinalCltvExpiry match { - case None => SendPayment(amount_msat, pr.paymentHash, pr.nodeId, maxFeePct = nodeParams.maxPaymentFee) - case Some(minFinalCltvExpiry) => SendPayment(amount_msat, pr.paymentHash, pr.nodeId, assistedRoutes = Nil, minFinalCltvExpiry, maxFeePct = nodeParams.maxPaymentFee) + case None => SendPayment(amount_msat, pr.paymentHash, pr.nodeId) + case Some(minFinalCltvExpiry) => SendPayment(amount_msat, pr.paymentHash, pr.nodeId, assistedRoutes = Nil, minFinalCltvExpiry) } completeRpcFuture(req.id, (paymentInitiator ? sendPayment).mapTo[PaymentResult].map { case s: PaymentSucceeded => s diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentLifecycle.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentLifecycle.scala index 2f8e7cb36b..9f458a89c6 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentLifecycle.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentLifecycle.scala @@ -55,15 +55,8 @@ class PaymentLifecycle(sourceNodeId: PublicKey, router: ActorRef, register: Acto val finalExpiry = Globals.blockCount.get().toInt + c.finalCltvExpiry.toInt + 1 val (cmd, sharedSecrets) = buildCommand(c.amountMsat, finalExpiry, c.paymentHash, hops) - val feePct = (cmd.amountMsat - c.amountMsat) / c.amountMsat.toDouble // c.amountMsat is required to be > 0, have to convert to double, otherwise will be rounded - if (feePct > c.maxFeePct) { - log.info(s"cheapest route found is too expensive: feePct=$feePct maxFeePct=${c.maxFeePct}") - reply(s, PaymentFailed(c.paymentHash, failures = failures :+ LocalFailure(RouteTooExpensive(feePct, c.maxFeePct)))) - stop(FSM.Normal) - } else { - register ! Register.ForwardShortId(firstHop.lastUpdate.shortChannelId, cmd) - goto(WAITING_FOR_PAYMENT_COMPLETE) using WaitingForComplete(s, c, cmd, failures, sharedSecrets, ignoreNodes, ignoreChannels, hops) - } + register ! Register.ForwardShortId(firstHop.lastUpdate.shortChannelId, cmd) + goto(WAITING_FOR_PAYMENT_COMPLETE) using WaitingForComplete(s, c, cmd, failures, sharedSecrets, ignoreNodes, ignoreChannels, hops) case Event(Status.Failure(t), WaitingForRoute(s, c, failures)) => reply(s, PaymentFailed(c.paymentHash, failures = failures :+ LocalFailure(t))) @@ -199,7 +192,6 @@ object PaymentLifecycle { assistedRoutes: Seq[Seq[ExtraHop]] = Nil, finalCltvExpiry: Long = Channel.MIN_CLTV_EXPIRY, maxAttempts: Int = 5, - maxFeePct: Double = 0.03, randomize: Option[Boolean] = None, routeParams: Option[RouteParams] = None) { require(amountMsat > 0, s"amountMsat must be > 0") @@ -224,10 +216,6 @@ object PaymentLifecycle { case object WAITING_FOR_ROUTE extends State case object WAITING_FOR_PAYMENT_COMPLETE extends State - val percentageFormatter = NumberFormat.getPercentInstance(Locale.US) // force US locale to always get "fee=0.272% max=0.1%" (otherwise depending on locale it can be "fee=0,272 % max=0,1 %") - percentageFormatter.setMaximumFractionDigits(3) - case class RouteTooExpensive(feePct: Double, maxFeePct: Double) extends RuntimeException(s"cheapest route found is too expensive: fee=${percentageFormatter.format(feePct)} max=${percentageFormatter.format(maxFeePct)}") - // @formatter:on diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala b/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala index 0488e2f055..88a75c2f8f 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala @@ -84,7 +84,6 @@ object TestConstants { watcherType = BITCOIND, paymentRequestExpiry = 1 hour, maxPendingPaymentRequests = 10000000, - maxPaymentFee = 0.03, minFundingSatoshis = 1000L, routerConf = RouterConf( randomizeRouteSelection = false, @@ -151,7 +150,6 @@ object TestConstants { watcherType = BITCOIND, paymentRequestExpiry = 1 hour, maxPendingPaymentRequests = 10000000, - maxPaymentFee = 0.03, minFundingSatoshis = 1000L, routerConf = RouterConf( randomizeRouteSelection = false, diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentLifecycleSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentLifecycleSpec.scala index a0a6e485ef..28a2f3acb7 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentLifecycleSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentLifecycleSpec.scala @@ -67,11 +67,11 @@ class PaymentLifecycleSpec extends BaseRouterSpec { paymentFSM ! SubscribeTransitionCallBack(monitor.ref) val CurrentState(_, WAITING_FOR_REQUEST) = monitor.expectMsgClass(classOf[CurrentState[_]]) - val request = SendPayment(defaultAmountMsat, defaultPaymentHash, d, maxFeePct = 0.001) + val request = SendPayment(defaultAmountMsat, defaultPaymentHash, d, routeParams = Some(RouteParams(maxFeeBaseMsat = 0, maxFeePct = 0.001, routeMaxLength = 20, routeMaxCltv = 2016))) sender.send(paymentFSM, request) val Transition(_, WAITING_FOR_REQUEST, WAITING_FOR_ROUTE) = monitor.expectMsgClass(classOf[Transition[_]]) - val Seq(LocalFailure(RouteTooExpensive(_, _))) = sender.expectMsgType[PaymentFailed].failures + val Seq(LocalFailure(RouteNotFound)) = sender.expectMsgType[PaymentFailed].failures } test("payment failed (unparsable failure)") { fixture => diff --git a/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/Handlers.scala b/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/Handlers.scala index 78c8bc6c29..c4737adf98 100644 --- a/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/Handlers.scala +++ b/eclair-node-gui/src/main/scala/fr/acinq/eclair/gui/Handlers.scala @@ -88,7 +88,7 @@ class Handlers(fKit: Future[Kit])(implicit ec: ExecutionContext = ExecutionConte (for { kit <- fKit sendPayment = req.minFinalCltvExpiry match { - case None => SendPayment(amountMsat, req.paymentHash, req.nodeId, req.routingInfo, maxFeePct = kit.nodeParams.maxPaymentFee) + case None => SendPayment(amountMsat, req.paymentHash, req.nodeId, req.routingInfo) case Some(minFinalCltvExpiry) => SendPayment(amountMsat, req.paymentHash, req.nodeId, req.routingInfo, finalCltvExpiry = minFinalCltvExpiry) } res <- (kit.paymentInitiator ? sendPayment).mapTo[PaymentResult]