-
Notifications
You must be signed in to change notification settings - Fork 404
Add simple probing API #1567
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
Add simple probing API #1567
Conversation
f6c9a47
to
c0a9e1a
Compare
Codecov Report
@@ Coverage Diff @@
## main #1567 +/- ##
==========================================
- Coverage 91.07% 90.93% -0.15%
==========================================
Files 80 80
Lines 44128 45110 +982
Branches 44128 45110 +982
==========================================
+ Hits 40190 41020 +830
- Misses 3938 4090 +152
Continue to review full report at Codecov.
|
Hm, also unsure why |
Cool to see probing get better support. One question on implementing this. You'd still go through the Event manager to find One thing I was finding when I was doing probing is that I needed access to the error reasons to really discern the reason for the probe failure. In my fork of LDK, I had to remove the test config flags here: rust-lightning/lightning/src/util/events.rs Lines 380 to 383 in a600eee
Maybe a PR to remove that could be useful here? Or maybe a better way to discern the errors. My implementation is here if curious: |
lightning-invoice/src/payment.rs
Outdated
@@ -256,6 +272,11 @@ pub trait Router<S: Score> { | |||
&self, payer: &PublicKey, route_params: &RouteParameters, payment_hash: &PaymentHash, | |||
first_hops: Option<&[&ChannelDetails]>, scorer: &S | |||
) -> Result<Route, LightningError>; | |||
|
|||
/// Builds a [`Route`] from `payer` along the given path. | |||
fn build_route_from_hops( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its kinda awkward to make this a part of the Router
interface just so that the send_probe_along_path
method takes a pubkey list, we could just have that method take a Route
and let the user build the route any way they want (either by getting a route or by getting a pubkey list). That seems like a strictly more general API and reduces the method set in the Router
trait which is nice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, but isn't the interface in InvoicePayer
supposed to wrap more functionality in a single method call, such as pay_invoice
, pay_pubkey
? If send_route_along_path
should take a Route
I honestly don't see it's utility over simply using send_probing_payment
in ChannelManager
directly, i.e., I'd just leave it out of InvoicePayer
entirely?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, seems allowing arbitrary Route
s could complicated the semantics, too, if say the route has more than one path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, but isn't the interface in InvoicePayer supposed to wrap more functionality in a single method call, such as pay_invoice, pay_pubkey?
Sure, but by that argument we should have a probe_node
method, not a probe_preselected_path
method. I don't quite understand what the exact use-case is for a prober that probes a given path, selected by public keys (how did the user generate that path?) that isn't equivalently covered by a Route
.
If send_route_along_path should take a Route I honestly don't see it's utility over simply using send_probing_payment in ChannelManager directly, i.e., I'd just leave it out of InvoicePayer entirely?
I understood it as something that corrects the event handling for users. That said, with the switch to dedicated probe-success-fail events, I'm not sure what the point would be as-is either. I do think we need the scorer and the router to be able to "intelligently" pick routes to probe, but that seems like a prereq here, not something in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What may make sense is to scope this PR down to just the channelmanager API changes and to handle the events in the InvoicePayer
like we do other payment events. Then we can do a followup that has some kind of intelligent probe-route-building API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright. I agree that eventually we'd want to give a range of probing tools to the user, the main one probably being a method probing a particular channel rather than a full path. I'd however still argue probing a path should be part of that toolbox. That said I'm fine with landing this only providing ChannelManager
's send_probe
and working out the details of the API in a follow-up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I don't disagree that probing a path and a channel are useful, but I think probably the eventual end-goal should be either send_probe()
or probe_node(node_id: PublicKey)
- users either want to probe and have the prober handle everything (probably looking at recent payment history and finding nodes that it has had a hard time paying and probe alternative paths to those nodes) or probe trying to improve knowledge of how to reach a specific node.
Yes, that's the idea.
Ah, interesting. So far I though I could get around that since we have the |
22ac083
to
585f8d8
Compare
a3cff9b
to
480887d
Compare
Rebased. |
So my use case is pretty non-standard, since I'm probing for unannounced channels, not balance. That said, there's a number of errors that could be returned to determine whether or not a probe was unsuccessful due to balance or some other error. For instance, fee amount or CLTV delta. However, I suppose if you just want to know whether or not a payment made it all the way through to the end node, you could probably trigger off of Though it would be nice to have access to error code for more advanced use cases, even if not in the simple probing api. |
lightning-invoice/src/payment.rs
Outdated
@@ -256,6 +272,11 @@ pub trait Router<S: Score> { | |||
&self, payer: &PublicKey, route_params: &RouteParameters, payment_hash: &PaymentHash, | |||
first_hops: Option<&[&ChannelDetails]>, scorer: &S | |||
) -> Result<Route, LightningError>; | |||
|
|||
/// Builds a [`Route`] from `payer` along the given path. | |||
fn build_route_from_hops( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, seems allowing arbitrary Route
s could complicated the semantics, too, if say the route has more than one path.
Yeah, I think the underlying assumption is that we would always create payments that would only fail by insufficient balance or at the final destination. I agree, allowing for more fine-grained / advanced control over probing would likely be a good follow up. |
Still no good idea regarding the fuzzer. @TheBlueMatt do you have a hunch? |
Oh, sorry, I missed that. The fuzzer test is sad cause you changed the format of what |
Ah good to know, was suspecting something like this. I assumed the comment you referenced to be addressed, since I removed the interface change here and will look into another API in a follow-up. Should I include something else here (apart from an end-to-end test)? EDIT: Huh, seems part of the 'remove interface' changes didn't make it into the commit previously. Should be properly removed now though. Sorry! |
Basically LGTM, just #1567 (comment) and fuzz to go. Do you mind if this get's squashed, @jkczyz ? |
Sure, go ahead and squash. |
Using this field just for MPP doesn't make sense when it could intuitively also be used to indicate single-path payments. We therefore rename `max_mpp_path_count` to `max_path_count` and make sure that a value of 1 ensures MPP is not even tried.
483eccf
to
fe6dd2b
Compare
Squashed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The following diff fixes the fuzz issue:
diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs
index b4ca316ed..fa0211aa2 100644
--- a/fuzz/src/full_stack.rs
+++ b/fuzz/src/full_stack.rs
@@ -393,7 +393,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
// Adding new calls to `KeysInterface::get_secure_random_bytes` during startup can change all the
// keys subsequently generated in this test. Rather than regenerating all the messages manually,
// it's easier to just increment the counter here so the keys don't change.
- keys_manager.counter.fetch_sub(1, Ordering::AcqRel);
+ keys_manager.counter.fetch_sub(2, Ordering::AcqRel);
let our_id = PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret(Recipient::Node).unwrap());
let network_graph = Arc::new(NetworkGraph::new(genesis_block(network).block_hash(), Arc::clone(&logger)));
let gossip_sync = Arc::new(P2PGossipSync::new(Arc::clone(&network_graph), None, Arc::clone(&logger)));
Thanks for the patch, the fuzzer seems happy now (at least locally). Squashed again. |
Ow, I think the fuzzer now fails differently? |
Oops, plus:
|
Alright, try, try again. |
When we send payment probes, we generate the [`PaymentHash`] based on a probing cookie secret and a random [`PaymentId`]. This allows us to discern probes from real payments, without keeping additional state.
This PR adds a simple API for sending payment probes and introduces the concept of probing cookies:
When we send payment probes, we generate the
PaymentHash
based on a probing cookie secret and a randomPaymentId
. This allows us to discern probes from real payments, without keeping additional state.I also included a minor refactor to generalize
PaymentParameters::max_mpp_path_count
(now:max_path_count
) and to make sure a maximum allowed path count of 1 results in us never trying to find an MPP path (i.e.,allow_mpp = false
).