Skip to content

Addition of API calls checkinvoice and findroute#475

Merged
pm47 merged 6 commits intoACINQ:masterfrom
n1bor:api-updates
Mar 24, 2018
Merged

Addition of API calls checkinvoice and findroute#475
pm47 merged 6 commits intoACINQ:masterfrom
n1bor:api-updates

Conversation

@n1bor
Copy link
Contributor

@n1bor n1bor commented Mar 5, 2018

checkinvoice parses an invoice/PaymentRequest and returns the JSON object. Usecase is that you need to be 100% sure that Eclair is paying the amount you expect! Easy to be factor of 1000 out if someone has a bug!

checkroute takes an invoice and checks if we have a route to pay at that moment. Is useful when you do not want to accept a request for payment you know you can not make.

Includes tests for checkroute.

@n1bor
Copy link
Contributor Author

n1bor commented Mar 5, 2018

fixed bug in help docs and squashed commits.
And travis worked this time too!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should reject the method if the paymentRequest argument is missing, with something like:

case _ => reject(UnknownParamsRejection(req.id, "[payment_request]"))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as checkinvoice, the method should be rejected if the paymentRequest argument is missing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An amount is not required for a payment request (donation cases) and is not needed to find a route

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arh - was hoping check route also checked the route had enough funds. Guess it does not.
Fixed

@dpad85
Copy link
Member

dpad85 commented Mar 6, 2018

Great stuff, thanks for the PR!

I noticed that the failures field in the PaymentFailed is not propertly serialized to JSON and, when a route can not be found, we get an empty failure:

{
  "paymentHash": "ff75b8778563b85d525569a8259862ee9bc50ea7b5d781015dd957c17eaca496",
  "failures": [
    {
      "t": {}
    }
  ]
}

This can be fixed with a ThrowableSerializer, something like:

class ThrowableSerializer extends CustomSerializer[Throwable](format => ({ null }, {
  case t: Throwable if t.getMessage != null => JString(t.getMessage)
  case t: Throwable => JString(t.getClass.getSimpleName)
}))

which then gives

...
"failures": [
  {
    "t": "route not found"
  }

Could you add it to the JsonSerializers file (and to the formats field in Service?)

Copy link
Member

@pm47 pm47 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the use case for checkinvoice, although I'm not sure just printing out the payment request will help, because there are usually a lot of zeroes. FWIW, the human-readable part of the payment request was designed to do just that, even if it is arguably difficult to read.

I think having a checkroute (or maybe findroute) method is nice, but you don't need to go through PaymentLifecycle (which role is to manage payment failures), instead just query the router directly, like allnodes/allchannels/allupdates do: send a RouteRequest and you'll get a RouteResponse.

edit: I also think this findroute method should take either a nodeid or a payment request as input.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: remove unnecessary braces around completeRpc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arh - using the router is much simpler! Updated.
Use-case for both these is another app using the API - in checkinvoice case is to check amount is what we are expecting - before paying with send. So zeros fine.

@dpad85
Copy link
Member

dpad85 commented Mar 10, 2018

Do you mind if I push 1 or 2 commits on your branch to fix some indentation issues? I also would like to add a serializer for the object returned by the findroute call, so that it returns something like:

{
  "hops": "node1 -> node2 -> node3"
  "channels": "shortid1 -> shortid2"
}

@n1bor
Copy link
Contributor Author

n1bor commented Mar 12, 2018

@dpad85 - sure change however you want. Just want to be able to identify if there is a route, and get from the invoice the amount.
Think the more detail in the API the better. As then future proof for other use-cases.

@n1bor
Copy link
Contributor Author

n1bor commented Mar 23, 2018

rebased.. any chance of getting this merged as have some other api changes to come.

Copy link
Member

@pm47 pm47 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few nitpick comments, please use proper identation and formatting (Ctrl+Shift+L on IntelliJ)

Also, please merge against master as there has been conflicting changes.

Thanks!

case "checkinvoice" => req.params match {
case JString(paymentRequest) :: Nil => Try(PaymentRequest.read(paymentRequest)) match {
case Success(pr) => {
completeRpc(req.id,pr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

superfluous { } around completeRpc(req.id,pr)

case JString(nodeId) :: Nil if nodeId.length()==66 =>
Try(PublicKey(nodeId)) match {
case Success(pk) => completeRpcFuture(req.id, (router ? RouteRequest(appKit.nodeParams.nodeId, pk) ).mapTo[RouteResponse] )
case (Failure(_)) => reject(RpcValidationRejection(req.id, s"invalid nodeId hash: '$nodeId'"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove () around Failure(_)

}

case JString(paymentRequest) :: Nil => Try(PaymentRequest.read(paymentRequest)) match {
case pr@Success(PaymentRequest(_,_,_,_,_,_)) =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use case Success(pr: PaymentRequest) => instead

@pm47 pm47 changed the title Addition of API calls checkinvoice and checkroute Addition of API calls checkinvoice and findroute Mar 23, 2018
@dpad85
Copy link
Member

dpad85 commented Mar 23, 2018

@pm47 can you update your review with the latest commits?

Copy link
Member

@pm47 pm47 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API doc needs to be updated in README.md

@n1bor
Copy link
Contributor Author

n1bor commented Mar 23, 2018

Updated README - sorry about commit message - thought I changed that before I pushed??

pm47
pm47 previously approved these changes Mar 23, 2018
@n1bor
Copy link
Contributor Author

n1bor commented Mar 23, 2018

annoying timeouts... can we add akka.test.timefactor=10 or something? As expecting to use travis as a performance tester is not a good idea?

@pm47 pm47 merged commit 1a8cb2a into ACINQ:master Mar 24, 2018
@pm47
Copy link
Member

pm47 commented Mar 24, 2018

@n1bor flaky tests were actually due to a regression fixed in 64c15b4. Believe it or not sometimes tests work as expected! 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants