Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

routing: extend trackpayment with htlc events #3972

Merged
merged 8 commits into from
Apr 8, 2020

Conversation

joostjager
Copy link
Contributor

@joostjager joostjager commented Jan 29, 2020

Currently there is inconsistency between the payment status as reported via ListPayment and the status notified through routerrpc.SendPayment/TrackPayment. With this PR, the same full payment struct is returned by both rpc calls.

In addition to that, routerrpc notifications are now sent out for every change to the payment. This will allow users to track progress of their (multi-parts) payments, either via lncli (use the newly added --show_inflight flag) or via graphical user interfaces/apps if support is added there. Previously only the final state of the payment was reported.

Note: The HTLCAttempt_IN_FLIGHT update will be sent out before the htlc is actually in flight on the link. Launching a QueryRoutes at that point will not see the balance change yet. This is relevant for applications that use the output of TrackPayment to implement their own payment loop.

@Roasbeef Roasbeef added gRPC mpp payments Related to invoices/payments routing rpc Related to the RPC interface labels Feb 3, 2020
@joostjager joostjager added the incomplete WIP PR, not fully finalized, but light review possible label Apr 3, 2020
@joostjager joostjager force-pushed the notify-htlc-arrival branch 4 times, most recently from 6152911 to 874c0e1 Compare April 6, 2020 10:46
@joostjager joostjager marked this pull request as ready for review April 6, 2020 10:48
@joostjager joostjager requested review from cfromknecht and removed request for halseth April 6, 2020 10:48
@joostjager joostjager removed the incomplete WIP PR, not fully finalized, but light review possible label Apr 6, 2020
@joostjager
Copy link
Contributor Author

Ready for concept ack

Todo: add ConcurrentQueue for notifications, to prevent rpc users from blocking the payment process

@joostjager joostjager force-pushed the notify-htlc-arrival branch 5 times, most recently from 313d220 to 40e8ac4 Compare April 6, 2020 14:43
@joostjager
Copy link
Contributor Author

ConcurrentQueue added. Also used multimutex to prevent a global lock around db tx and notification. Initially I had the global lock, but that also caused the async payments benchmark to fail. Probably too slow.

routing/control_tower.go Outdated Show resolved Hide resolved
Copy link
Contributor

@halseth halseth left a comment

Choose a reason for hiding this comment

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

Excellent PR, really makes it easier to reason about the control tower subscription logic 👍

lnrpc/routerrpc/router_backend.go Outdated Show resolved Hide resolved
lnrpc/rpc.proto Outdated Show resolved Hide resolved
}

// Close outgoing channel.
close(cq.chanOut)
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe this should be done on quit also?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think so. It would signal a clean end to the queue, which isn't the case for quit

queue/queue.go Show resolved Hide resolved
// a given hash will hold the mutex to be used by all
// callers requesting access for the hash, in addition to
// the count of callers.
mutexes map[lntypes.Hash]*cntMutex
Copy link
Contributor

Choose a reason for hiding this comment

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

can't we just take 4 bytes of the hash and use the existing uint64 mutex? Alternatively use interface{} as the key type.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interesting suggestion. That will work, unless people use non-random hashes (for invoices that are never settled)? There is some cost in terms of understandability. Not sure if it weighs up.

Copy link
Contributor

@halseth halseth Apr 7, 2020

Choose a reason for hiding this comment

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

Worst case it will just have to wait a bit longer before accessing the DB in those cases. I think it is nice to avoid the code duplication, as long as we don't have generics.

Do avoid the scenario you mention, could also a add a simple method

func (h Hash) Uint64Key() uint64 {
      return uint64(sha256(h[:])[0:4])
}

but maybe that is taking it too far

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will leave this thread open for others to comment on.

Copy link
Contributor

Choose a reason for hiding this comment

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

no strong preference fro me, tho i think a hash map would be a useful addition to multimutex as a library

Copy link
Contributor Author

Choose a reason for hiding this comment

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

leaving hash map in then

routing/control_tower.go Show resolved Hide resolved
routing/control_tower.go Outdated Show resolved Hide resolved
routing/control_tower.go Show resolved Hide resolved
routing/control_tower.go Show resolved Hide resolved
lnrpc/routerrpc/router_backend.go Outdated Show resolved Hide resolved
lnrpc/routerrpc/router_backend.go Outdated Show resolved Hide resolved
channeldb/payment_control.go Show resolved Hide resolved
lnrpc/routerrpc/router_server.go Show resolved Hide resolved
routing/control_tower.go Show resolved Hide resolved
routing/control_tower.go Show resolved Hide resolved
// a given hash will hold the mutex to be used by all
// callers requesting access for the hash, in addition to
// the count of callers.
mutexes map[lntypes.Hash]*cntMutex
Copy link
Contributor

Choose a reason for hiding this comment

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

no strong preference fro me, tho i think a hash map would be a useful addition to multimutex as a library

Copy link
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

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

LGTM 🦊

Re the breaking proto changes: as mentioned offline, in the end we haven't committed to making this a stable API yet. I think we also envisioned from the start that AMP/MPP would likely result in a series of changes in the API as things became more concrete through development. With 0.10, as we're now moving to always compile it in, and we may also have the API docs render the sub-servers as well, we can now start to publicly commit to gradual freezing of the interface.

As mentioned offline, a blog post explaining how to interact with and track MPP for 0.10 will go a long way.

@joostjager joostjager force-pushed the notify-htlc-arrival branch 2 times, most recently from 3cdbd28 to 10919c4 Compare April 8, 2020 06:33
This commit fixes the inconsistency between the payment state as
reported by routerrpc.SendPayment/routerrpc.TrackPayment and the main
rpc ListPayments call.

In addition to that, payment state changes are now sent out for every
state change. This opens the door to user interfaces giving more
feedback to the user about the payment process. This is especially
interesting for multi-part payments.
@joostjager
Copy link
Contributor Author

This PR replaces the messages in the stream of SendPayment and TrackPayment with a completely different message. Running an application that isn't updated against this new rpc yields:

grpc: failed to unmarshal the received message unexpected EOF

@alexbosworth
Copy link
Contributor

alexbosworth commented Apr 8, 2020

This PR replaces the messages in the stream of SendPayment and TrackPayment with a completely different message. Running an application that isn't updated against this new rpc yields:

grpc: failed to unmarshal the received message unexpected EOF

That's pretty rough, it is because it is not a new RPC, it's an existing RPC that was overwritten in a way that gRPC was not designed to support

@Roasbeef
Copy link
Member

Roasbeef commented Apr 8, 2020

That's pretty rough

That's perfectively acceptable as this is an experimental RPC server, which was only envisioned to only near a final form after MPP/AMP was implemented, which is now. Compare this to the external sendpayment and llist/subscribe invoice calls which haven't changed significantly since they were created.

Copy link
Contributor

@cfromknecht cfromknecht left a comment

Choose a reason for hiding this comment

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

LGTM 🔥

The main SendPayment rpcs have been in place for 3+ years now w/o breaking changes. IMO it's better to break the API before moving routerrpc out of experimental than end up in a mediocre middle ground. If we're lucky routerrpc.SendPayment will be more Lindy than the original, so in the grand scheme of things the amortized costs are pretty marginal for users who happen to be using the experimental RPCs early. Seems a little cart before the horse to have experimental integrations prevent shipping a polished product for the masses.

@alexbosworth
Copy link
Contributor

By rough I mean that it's more difficult to deal with as a consumer. So if you were building on this, you will now have a harder job adapting to the change than otherwise might be possible

@Roasbeef Roasbeef merged commit 3ad7ab2 into lightningnetwork:master Apr 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
gRPC mpp payments Related to invoices/payments routing rpc Related to the RPC interface
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants