Skip to content

Commit 3b2bc57

Browse files
authored
Add maxCltvExpiryDelta parameter to findRoute* APIs (#3234)
We add a parameter to `findroute` API variants to limit the total CLTV expiry delta of the route(s) returned. Fixes #2617
1 parent 288c541 commit 3b2bc57

File tree

7 files changed

+32
-30
lines changed

7 files changed

+32
-30
lines changed

docs/release-notes/eclair-vnext.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ If you still have such channels, eclair won't start: you will need to close thos
1515

1616
### API changes
1717

18-
<insert changes>
18+
- `findroute`, `findroutetonode` and `findroutebetweennodes` now include a `maxCltvExpiryDelta` parameter (#3234)
1919

2020
### Miscellaneous improvements and bug fixes
2121

eclair-core/src/main/scala/fr/acinq/eclair/Eclair.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher.WatchFundingSpentTriggered
3333
import fr.acinq.eclair.blockchain.bitcoind.rpc.BitcoinCoreClient
3434
import fr.acinq.eclair.blockchain.bitcoind.rpc.BitcoinCoreClient.{AddressType, Descriptors, WalletTx}
3535
import fr.acinq.eclair.blockchain.fee.{ConfirmationTarget, FeeratePerByte, FeeratePerKw}
36-
import fr.acinq.eclair.channel.ChannelSpendSignature.PartialSignatureWithNonce
3736
import fr.acinq.eclair.channel._
3837
import fr.acinq.eclair.crypto.Sphinx
3938
import fr.acinq.eclair.db.AuditDb.{NetworkFee, Stats}
@@ -152,9 +151,9 @@ trait Eclair {
152151

153152
def cpfpBumpFees(targetFeeratePerByte: FeeratePerByte, outpoints: Set[OutPoint]): Future[TxId]
154153

155-
def findRoute(targetNodeId: PublicKey, amount: MilliSatoshi, pathFindingExperimentName_opt: Option[String], extraEdges: Seq[Invoice.ExtraEdge] = Seq.empty, includeLocalChannelCost: Boolean = false, ignoreNodeIds: Seq[PublicKey] = Seq.empty, ignoreShortChannelIds: Seq[ShortChannelId] = Seq.empty, maxFee_opt: Option[MilliSatoshi] = None)(implicit timeout: Timeout): Future[RouteResponse]
154+
def findRoute(targetNodeId: PublicKey, amount: MilliSatoshi, pathFindingExperimentName_opt: Option[String], extraEdges: Seq[Invoice.ExtraEdge] = Seq.empty, includeLocalChannelCost: Boolean = false, ignoreNodeIds: Seq[PublicKey] = Seq.empty, ignoreShortChannelIds: Seq[ShortChannelId] = Seq.empty, maxFee_opt: Option[MilliSatoshi] = None, maxCltvExpiryDelta_opt: Option[CltvExpiryDelta] = None)(implicit timeout: Timeout): Future[RouteResponse]
156155

157-
def findRouteBetween(sourceNodeId: PublicKey, targetNodeId: PublicKey, amount: MilliSatoshi, pathFindingExperimentName_opt: Option[String], extraEdges: Seq[Invoice.ExtraEdge] = Seq.empty, includeLocalChannelCost: Boolean = false, ignoreNodeIds: Seq[PublicKey] = Seq.empty, ignoreShortChannelIds: Seq[ShortChannelId] = Seq.empty, maxFee_opt: Option[MilliSatoshi] = None)(implicit timeout: Timeout): Future[RouteResponse]
156+
def findRouteBetween(sourceNodeId: PublicKey, targetNodeId: PublicKey, amount: MilliSatoshi, pathFindingExperimentName_opt: Option[String], extraEdges: Seq[Invoice.ExtraEdge] = Seq.empty, includeLocalChannelCost: Boolean = false, ignoreNodeIds: Seq[PublicKey] = Seq.empty, ignoreShortChannelIds: Seq[ShortChannelId] = Seq.empty, maxFee_opt: Option[MilliSatoshi] = None, maxCltvExpiryDelta_opt: Option[CltvExpiryDelta] = None)(implicit timeout: Timeout): Future[RouteResponse]
158157

159158
def sendToRoute(recipientAmount_opt: Option[MilliSatoshi], externalId_opt: Option[String], parentId_opt: Option[UUID], invoice: Bolt11Invoice, route: PredefinedRoute)(implicit timeout: Timeout): Future[SendPaymentToRouteResponse]
160159

@@ -459,8 +458,8 @@ class EclairImpl(val appKit: Kit) extends Eclair with Logging with SpendFromChan
459458
}
460459
}
461460

462-
override def findRoute(targetNodeId: PublicKey, amount: MilliSatoshi, pathFindingExperimentName_opt: Option[String], extraEdges: Seq[Invoice.ExtraEdge] = Seq.empty, includeLocalChannelCost: Boolean = false, ignoreNodeIds: Seq[PublicKey] = Seq.empty, ignoreShortChannelIds: Seq[ShortChannelId] = Seq.empty, maxFee_opt: Option[MilliSatoshi] = None)(implicit timeout: Timeout): Future[RouteResponse] =
463-
findRouteBetween(appKit.nodeParams.nodeId, targetNodeId, amount, pathFindingExperimentName_opt, extraEdges, includeLocalChannelCost, ignoreNodeIds, ignoreShortChannelIds, maxFee_opt)
461+
override def findRoute(targetNodeId: PublicKey, amount: MilliSatoshi, pathFindingExperimentName_opt: Option[String], extraEdges: Seq[Invoice.ExtraEdge] = Seq.empty, includeLocalChannelCost: Boolean = false, ignoreNodeIds: Seq[PublicKey] = Seq.empty, ignoreShortChannelIds: Seq[ShortChannelId] = Seq.empty, maxFee_opt: Option[MilliSatoshi] = None, maxCltvExpiryDelta_opt: Option[CltvExpiryDelta] = None)(implicit timeout: Timeout): Future[RouteResponse] =
462+
findRouteBetween(appKit.nodeParams.nodeId, targetNodeId, amount, pathFindingExperimentName_opt, extraEdges, includeLocalChannelCost, ignoreNodeIds, ignoreShortChannelIds, maxFee_opt, maxCltvExpiryDelta_opt)
464463

465464
private def getRouteParams(pathFindingExperimentName_opt: Option[String]): Either[IllegalArgumentException, RouteParams] = {
466465
pathFindingExperimentName_opt match {
@@ -472,15 +471,16 @@ class EclairImpl(val appKit: Kit) extends Eclair with Logging with SpendFromChan
472471
}
473472
}
474473

475-
override def findRouteBetween(sourceNodeId: PublicKey, targetNodeId: PublicKey, amount: MilliSatoshi, pathFindingExperimentName_opt: Option[String], extraEdges: Seq[Invoice.ExtraEdge] = Seq.empty, includeLocalChannelCost: Boolean = false, ignoreNodeIds: Seq[PublicKey] = Seq.empty, ignoreShortChannelIds: Seq[ShortChannelId] = Seq.empty, maxFee_opt: Option[MilliSatoshi] = None)(implicit timeout: Timeout): Future[RouteResponse] = {
474+
override def findRouteBetween(sourceNodeId: PublicKey, targetNodeId: PublicKey, amount: MilliSatoshi, pathFindingExperimentName_opt: Option[String], extraEdges: Seq[Invoice.ExtraEdge] = Seq.empty, includeLocalChannelCost: Boolean = false, ignoreNodeIds: Seq[PublicKey] = Seq.empty, ignoreShortChannelIds: Seq[ShortChannelId] = Seq.empty, maxFee_opt: Option[MilliSatoshi] = None, maxCltvExpiryDelta_opt: Option[CltvExpiryDelta] = None)(implicit timeout: Timeout): Future[RouteResponse] = {
476475
getRouteParams(pathFindingExperimentName_opt) match {
477476
case Right(routeParams) =>
478477
val target = ClearRecipient(targetNodeId, Features.empty, amount, CltvExpiry(appKit.nodeParams.currentBlockHeight), ByteVector32.Zeroes, extraEdges)
479478
val routeParams1 = routeParams.copy(
480479
includeLocalChannelCost = includeLocalChannelCost,
481480
boundaries = routeParams.boundaries.copy(
482481
maxFeeFlat = maxFee_opt.getOrElse(routeParams.boundaries.maxFeeFlat),
483-
maxFeeProportional = maxFee_opt.map(_ => 0.0).getOrElse(routeParams.boundaries.maxFeeProportional)
482+
maxFeeProportional = maxFee_opt.map(_ => 0.0).getOrElse(routeParams.boundaries.maxFeeProportional),
483+
maxCltv = maxCltvExpiryDelta_opt.getOrElse(routeParams.boundaries.maxCltv),
484484
)
485485
)
486486
for {

eclair-core/src/test/scala/fr/acinq/eclair/EclairImplSpec.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,6 @@ class EclairImplSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with I
343343
val eclair = new EclairImpl(kit)
344344
val route = PredefinedNodeRoute(1000 msat, Seq(randomKey().publicKey))
345345
val parentId = UUID.randomUUID()
346-
val secret = randomBytes32()
347346
val pr = Bolt11Invoice(Block.LivenetGenesisBlock.hash, Some(1234 msat), ByteVector32.One, randomKey(), Right(randomBytes32()), CltvExpiryDelta(18))
348347
eclair.sendToRoute(Some(1200 msat), Some("42"), Some(parentId), pr, route)
349348
val sendPaymentToRoute = paymentInitiator.expectMsgType[SendPaymentToRoute]

eclair-node/src/main/scala/fr/acinq/eclair/api/directives/ExtraDirectives.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import fr.acinq.eclair.api.serde.JsonSupport._
2929
import fr.acinq.eclair.blockchain.fee.ConfirmationPriority
3030
import fr.acinq.eclair.payment.Bolt11Invoice
3131
import fr.acinq.eclair.wire.protocol.OfferTypes.Offer
32-
import fr.acinq.eclair.{MilliSatoshi, Paginated, ShortChannelId, TimestampSecond}
32+
import fr.acinq.eclair.{CltvExpiryDelta, MilliSatoshi, Paginated, ShortChannelId, TimestampSecond}
3333

3434
import scala.concurrent.Future
3535
import scala.concurrent.duration.DurationInt
@@ -52,6 +52,7 @@ trait ExtraDirectives extends Directives {
5252
val ignoreNodeIdsFormParam: NameUnmarshallerReceptacle[List[PublicKey]] = "ignoreNodeIds".as[List[PublicKey]](pubkeyListUnmarshaller)
5353
val ignoreShortChannelIdsFormParam: NameUnmarshallerReceptacle[List[ShortChannelId]] = "ignoreShortChannelIds".as[List[ShortChannelId]](shortChannelIdsUnmarshaller)
5454
val maxFeeMsatFormParam: NameReceptacle[MilliSatoshi] = "maxFeeMsat".as[MilliSatoshi]
55+
val maxCltvExpiryDeltaFormParam: NameReceptacle[CltvExpiryDelta] = "maxCltvExpiryDelta".as[CltvExpiryDelta]
5556
val countFormParam: NameReceptacle[Int] = "count".as[Int]
5657
val skipFormParam: NameReceptacle[Int] = "skip".as[Int]
5758
val offerFormParam: NameUnmarshallerReceptacle[Offer] = "offer".as[Offer](offerUnmarshaller)

eclair-node/src/main/scala/fr/acinq/eclair/api/handlers/PathFinding.scala

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,27 @@ trait PathFinding {
3232
private implicit def ec: ExecutionContext = actorSystem.dispatcher
3333

3434
val findRoute: Route = postRequest("findroute") { implicit t =>
35-
formFields(invoiceFormParam, amountMsatFormParam.?, "pathFindingExperimentName".?, routeFormatFormParam.?, "includeLocalChannelCost".as[Boolean].?, ignoreNodeIdsFormParam.?, ignoreShortChannelIdsFormParam.?, maxFeeMsatFormParam.?) {
36-
case (invoice, None, pathFindingExperimentName_opt, routeFormat_opt, includeLocalChannelCost_opt, ignoreNodeIds_opt, ignoreChannels_opt, maxFee_opt) if invoice.amount_opt.nonEmpty =>
37-
complete(eclairApi.findRoute(invoice.nodeId, invoice.amount_opt.get, pathFindingExperimentName_opt, invoice.extraEdges, includeLocalChannelCost_opt.getOrElse(false), ignoreNodeIds = ignoreNodeIds_opt.getOrElse(Nil), ignoreShortChannelIds = ignoreChannels_opt.getOrElse(Nil), maxFee_opt = maxFee_opt).map(r => RouteFormat.format(r, routeFormat_opt)))
38-
case (invoice, Some(overrideAmount), pathFindingExperimentName_opt, routeFormat_opt, includeLocalChannelCost_opt, ignoreNodeIds_opt, ignoreChannels_opt, maxFee_opt) =>
39-
complete(eclairApi.findRoute(invoice.nodeId, overrideAmount, pathFindingExperimentName_opt, invoice.extraEdges, includeLocalChannelCost_opt.getOrElse(false), ignoreNodeIds = ignoreNodeIds_opt.getOrElse(Nil), ignoreShortChannelIds = ignoreChannels_opt.getOrElse(Nil), maxFee_opt = maxFee_opt).map(r => RouteFormat.format(r, routeFormat_opt)))
40-
case _ => reject(MalformedFormFieldRejection(
41-
"invoice", "The invoice must have an amount or you need to specify one using 'amountMsat'"
42-
))
35+
formFields(invoiceFormParam, amountMsatFormParam.?, "pathFindingExperimentName".?, routeFormatFormParam.?, "includeLocalChannelCost".as[Boolean].?, ignoreNodeIdsFormParam.?, ignoreShortChannelIdsFormParam.?, maxFeeMsatFormParam.?, maxCltvExpiryDeltaFormParam.?) {
36+
case (invoice, None, pathFindingExperimentName_opt, routeFormat_opt, includeLocalChannelCost_opt, ignoreNodeIds_opt, ignoreChannels_opt, maxFee_opt, maxCltv_opt) if invoice.amount_opt.nonEmpty =>
37+
complete(eclairApi.findRoute(invoice.nodeId, invoice.amount_opt.get, pathFindingExperimentName_opt, invoice.extraEdges, includeLocalChannelCost_opt.getOrElse(false), ignoreNodeIds = ignoreNodeIds_opt.getOrElse(Nil), ignoreShortChannelIds = ignoreChannels_opt.getOrElse(Nil), maxFee_opt = maxFee_opt, maxCltvExpiryDelta_opt = maxCltv_opt).map(r => RouteFormat.format(r, routeFormat_opt)))
38+
case (invoice, Some(overrideAmount), pathFindingExperimentName_opt, routeFormat_opt, includeLocalChannelCost_opt, ignoreNodeIds_opt, ignoreChannels_opt, maxFee_opt, maxCltv_opt) =>
39+
complete(eclairApi.findRoute(invoice.nodeId, overrideAmount, pathFindingExperimentName_opt, invoice.extraEdges, includeLocalChannelCost_opt.getOrElse(false), ignoreNodeIds = ignoreNodeIds_opt.getOrElse(Nil), ignoreShortChannelIds = ignoreChannels_opt.getOrElse(Nil), maxFee_opt = maxFee_opt, maxCltvExpiryDelta_opt = maxCltv_opt).map(r => RouteFormat.format(r, routeFormat_opt)))
40+
case _ =>
41+
reject(MalformedFormFieldRejection("invoice", "The invoice must have an amount or you need to specify one using 'amountMsat'"))
4342
}
4443
}
4544

4645
val findRouteToNode: Route = postRequest("findroutetonode") { implicit t =>
47-
formFields(nodeIdFormParam, amountMsatFormParam, "pathFindingExperimentName".?, routeFormatFormParam.?, "includeLocalChannelCost".as[Boolean].?, ignoreNodeIdsFormParam.?, ignoreShortChannelIdsFormParam.?, maxFeeMsatFormParam.?) {
48-
(nodeId, amount, pathFindingExperimentName_opt, routeFormat_opt, includeLocalChannelCost_opt, ignoreNodeIds_opt, ignoreChannels_opt, maxFee_opt) =>
49-
complete(eclairApi.findRoute(nodeId, amount, pathFindingExperimentName_opt, includeLocalChannelCost = includeLocalChannelCost_opt.getOrElse(false), ignoreNodeIds = ignoreNodeIds_opt.getOrElse(Nil), ignoreShortChannelIds = ignoreChannels_opt.getOrElse(Nil), maxFee_opt = maxFee_opt).map(r => RouteFormat.format(r, routeFormat_opt)))
46+
formFields(nodeIdFormParam, amountMsatFormParam, "pathFindingExperimentName".?, routeFormatFormParam.?, "includeLocalChannelCost".as[Boolean].?, ignoreNodeIdsFormParam.?, ignoreShortChannelIdsFormParam.?, maxFeeMsatFormParam.?, maxCltvExpiryDeltaFormParam.?) {
47+
(nodeId, amount, pathFindingExperimentName_opt, routeFormat_opt, includeLocalChannelCost_opt, ignoreNodeIds_opt, ignoreChannels_opt, maxFee_opt, maxCltv_opt) =>
48+
complete(eclairApi.findRoute(nodeId, amount, pathFindingExperimentName_opt, includeLocalChannelCost = includeLocalChannelCost_opt.getOrElse(false), ignoreNodeIds = ignoreNodeIds_opt.getOrElse(Nil), ignoreShortChannelIds = ignoreChannels_opt.getOrElse(Nil), maxFee_opt = maxFee_opt, maxCltvExpiryDelta_opt = maxCltv_opt).map(r => RouteFormat.format(r, routeFormat_opt)))
5049
}
5150
}
5251

5352
val findRouteBetweenNodes: Route = postRequest("findroutebetweennodes") { implicit t =>
54-
formFields("sourceNodeId".as[PublicKey], "targetNodeId".as[PublicKey], amountMsatFormParam, "pathFindingExperimentName".?, routeFormatFormParam.?, "includeLocalChannelCost".as[Boolean].?, ignoreNodeIdsFormParam.?, ignoreShortChannelIdsFormParam.?, maxFeeMsatFormParam.?) { (sourceNodeId, targetNodeId, amount, pathFindingExperimentName_opt, routeFormat_opt, includeLocalChannelCost_opt, ignoreNodeIds_opt, ignoreChannels_opt, maxFee_opt) =>
55-
complete(eclairApi.findRouteBetween(sourceNodeId, targetNodeId, amount, pathFindingExperimentName_opt, includeLocalChannelCost = includeLocalChannelCost_opt.getOrElse(false), ignoreNodeIds = ignoreNodeIds_opt.getOrElse(Nil), ignoreShortChannelIds = ignoreChannels_opt.getOrElse(Nil), maxFee_opt = maxFee_opt).map(r => RouteFormat.format(r, routeFormat_opt)))
53+
formFields("sourceNodeId".as[PublicKey], "targetNodeId".as[PublicKey], amountMsatFormParam, "pathFindingExperimentName".?, routeFormatFormParam.?, "includeLocalChannelCost".as[Boolean].?, ignoreNodeIdsFormParam.?, ignoreShortChannelIdsFormParam.?, maxFeeMsatFormParam.?, maxCltvExpiryDeltaFormParam.?) {
54+
(sourceNodeId, targetNodeId, amount, pathFindingExperimentName_opt, routeFormat_opt, includeLocalChannelCost_opt, ignoreNodeIds_opt, ignoreChannels_opt, maxFee_opt, maxCltv_opt) =>
55+
complete(eclairApi.findRouteBetween(sourceNodeId, targetNodeId, amount, pathFindingExperimentName_opt, includeLocalChannelCost = includeLocalChannelCost_opt.getOrElse(false), ignoreNodeIds = ignoreNodeIds_opt.getOrElse(Nil), ignoreShortChannelIds = ignoreChannels_opt.getOrElse(Nil), maxFee_opt = maxFee_opt, maxCltvExpiryDelta_opt = maxCltv_opt).map(r => RouteFormat.format(r, routeFormat_opt)))
5656
}
5757
}
5858

eclair-node/src/main/scala/fr/acinq/eclair/api/serde/FormParamExtractors.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import fr.acinq.eclair.io.NodeURI
2929
import fr.acinq.eclair.payment.Bolt11Invoice
3030
import fr.acinq.eclair.wire.protocol.OfferCodecs.blindedRouteCodec
3131
import fr.acinq.eclair.wire.protocol.OfferTypes.Offer
32-
import fr.acinq.eclair.{MilliSatoshi, ShortChannelId, TimestampSecond}
32+
import fr.acinq.eclair.{CltvExpiryDelta, MilliSatoshi, ShortChannelId, TimestampSecond}
3333
import scodec.bits.ByteVector
3434

3535
import java.util.UUID
@@ -68,6 +68,8 @@ object FormParamExtractors {
6868

6969
implicit val millisatoshiUnmarshaller: Unmarshaller[String, MilliSatoshi] = Unmarshaller.strict { str => MilliSatoshi(str.toLong) }
7070

71+
implicit val cltvExpiryDeltaUnmarshaller: Unmarshaller[String, CltvExpiryDelta] = Unmarshaller.strict { str => CltvExpiryDelta(str.toInt) }
72+
7173
implicit val feeratePerByteUnmarshaller: Unmarshaller[String, FeeratePerByte] = Unmarshaller.strict { str => FeeratePerByte(Satoshi(str.toLong)) }
7274

7375
implicit val outPointListUnmarshaller: Unmarshaller[String, List[OutPoint]] = listUnmarshaller(outPoint => {

eclair-node/src/test/scala/fr/acinq/eclair/api/ApiServiceSpec.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,7 @@ class ApiServiceSpec extends AnyFunSuite with ScalatestRouteTest with IdiomaticM
10021002

10031003
val eclair = mock[Eclair]
10041004
val mockService = new MockService(eclair)
1005-
eclair.findRoute(any, any, any, any, any, any, any, any)(any[Timeout]) returns Future.successful(Router.RouteResponse(Seq(Router.Route(456.msat, mockHops, None))))
1005+
eclair.findRoute(any, any, any, any, any, any, any, any, any)(any[Timeout]) returns Future.successful(Router.RouteResponse(Seq(Router.Route(456.msat, mockHops, None))))
10061006

10071007
// invalid format
10081008
Post("/findroute", FormData("format" -> "invalid-output-format", "invoice" -> serializedInvoice, "amountMsat" -> "456")) ~>
@@ -1012,7 +1012,7 @@ class ApiServiceSpec extends AnyFunSuite with ScalatestRouteTest with IdiomaticM
10121012
check {
10131013
assert(handled)
10141014
assert(status == BadRequest)
1015-
eclair.findRoute(invoice.nodeId, 456.msat, any, any, any, any, any, any)(any[Timeout]).wasNever(called)
1015+
eclair.findRoute(invoice.nodeId, 456.msat, any, any, any, any, any, any, any)(any[Timeout]).wasNever(called)
10161016
}
10171017

10181018
// default format
@@ -1025,7 +1025,7 @@ class ApiServiceSpec extends AnyFunSuite with ScalatestRouteTest with IdiomaticM
10251025
assert(status == OK)
10261026
val response = entityAs[String]
10271027
matchTestJson("findroute-nodeid", response)
1028-
eclair.findRoute(invoice.nodeId, 456.msat, any, any, any, any, any, any)(any[Timeout]).wasCalled(once)
1028+
eclair.findRoute(invoice.nodeId, 456.msat, any, any, any, any, any, any, any)(any[Timeout]).wasCalled(once)
10291029
}
10301030

10311031
Post("/findroute", FormData("format" -> "nodeId", "invoice" -> serializedInvoice, "amountMsat" -> "456")) ~>
@@ -1037,7 +1037,7 @@ class ApiServiceSpec extends AnyFunSuite with ScalatestRouteTest with IdiomaticM
10371037
assert(status == OK)
10381038
val response = entityAs[String]
10391039
matchTestJson("findroute-nodeid", response)
1040-
eclair.findRoute(invoice.nodeId, 456.msat, any, any, any, any, any, any)(any[Timeout]).wasCalled(twice)
1040+
eclair.findRoute(invoice.nodeId, 456.msat, any, any, any, any, any, any, any)(any[Timeout]).wasCalled(twice)
10411041
}
10421042

10431043
Post("/findroute", FormData("format" -> "shortChannelId", "invoice" -> serializedInvoice, "amountMsat" -> "456")) ~>
@@ -1049,7 +1049,7 @@ class ApiServiceSpec extends AnyFunSuite with ScalatestRouteTest with IdiomaticM
10491049
assert(status == OK)
10501050
val response = entityAs[String]
10511051
matchTestJson("findroute-scid", response)
1052-
eclair.findRoute(invoice.nodeId, 456.msat, any, any, any, any, any, any)(any[Timeout]).wasCalled(threeTimes)
1052+
eclair.findRoute(invoice.nodeId, 456.msat, any, any, any, any, any, any, any)(any[Timeout]).wasCalled(threeTimes)
10531053
}
10541054

10551055
Post("/findroute", FormData("format" -> "full", "invoice" -> serializedInvoice, "amountMsat" -> "456")) ~>
@@ -1061,7 +1061,7 @@ class ApiServiceSpec extends AnyFunSuite with ScalatestRouteTest with IdiomaticM
10611061
assert(status == OK)
10621062
val response = entityAs[String]
10631063
matchTestJson("findroute-full", response)
1064-
eclair.findRoute(invoice.nodeId, 456.msat, any, any, any, any, any, any)(any[Timeout]).wasCalled(fourTimes)
1064+
eclair.findRoute(invoice.nodeId, 456.msat, any, any, any, any, any, any, any)(any[Timeout]).wasCalled(fourTimes)
10651065
}
10661066
}
10671067

0 commit comments

Comments
 (0)