Skip to content

Commit

Permalink
Remove max-payment-fee in favor of router.search-max-fee-pct
Browse files Browse the repository at this point in the history
  • Loading branch information
araspitzu committed Feb 8, 2019
1 parent 4f7efc3 commit 61e7174
Show file tree
Hide file tree
Showing 7 changed files with 9 additions and 26 deletions.
3 changes: 1 addition & 2 deletions eclair-core/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}
}
2 changes: 0 additions & 2 deletions eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ case class NodeParams(keyManager: KeyManager,
watcherType: WatcherType,
paymentRequestExpiry: FiniteDuration,
maxPendingPaymentRequests: Int,
maxPaymentFee: Double,
minFundingSatoshis: Long,
routerConf: RouterConf) {

Expand Down Expand Up @@ -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),
Expand Down
6 changes: 3 additions & 3 deletions eclair-core/src/main/scala/fr/acinq/eclair/api/Service.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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))
})
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
Expand Down Expand Up @@ -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")
Expand All @@ -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


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ object TestConstants {
watcherType = BITCOIND,
paymentRequestExpiry = 1 hour,
maxPendingPaymentRequests = 10000000,
maxPaymentFee = 0.03,
minFundingSatoshis = 1000L,
routerConf = RouterConf(
randomizeRouteSelection = false,
Expand Down Expand Up @@ -151,7 +150,6 @@ object TestConstants {
watcherType = BITCOIND,
paymentRequestExpiry = 1 hour,
maxPendingPaymentRequests = 10000000,
maxPaymentFee = 0.03,
minFundingSatoshis = 1000L,
routerConf = RouterConf(
randomizeRouteSelection = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down

0 comments on commit 61e7174

Please sign in to comment.