-
Notifications
You must be signed in to change notification settings - Fork 385
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
Move InflightHtlcs
and Router
trait into ChannelManager
#1811
Move InflightHtlcs
and Router
trait into ChannelManager
#1811
Conversation
This helps prepare for moving the Router trait into ChannelManager, which will help allow ChannelManager to retrieve routes for trampoline
Codecov ReportBase: 90.72% // Head: 91.41% // Increases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## main #1811 +/- ##
==========================================
+ Coverage 90.72% 91.41% +0.69%
==========================================
Files 87 87
Lines 47361 51151 +3790
Branches 47361 51151 +3790
==========================================
+ Hits 42968 46761 +3793
+ Misses 4393 4390 -3
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
lightning-invoice/src/payment.rs
Outdated
&self, payer: &PublicKey, route_params: &RouteParameters, payment_hash: &PaymentHash, | ||
&self, payer: &PublicKey, route_params: &RouteParameters, |
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.
Not sure if we want to do this. It's for implementations wanting to support looking up pre-computed routes from a probe, according to the commit when added.
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.
It wouldn't be ideal to provide users with the payment hash in trampoline payments.
Do either of these options seem reasonable:
(1) make payment_hash into an Option<(PaymentHash, PaymentId)>
(2) make payment_hash into an Option<PaymentId>
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.
It wouldn't be ideal to provide users with the payment hash in trampoline payments.
Could you expand on this? Is the hash not available? Or is providing it harmful / misleading in some way?
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.
I think it's leaking the sender's privacy since it's not our payment
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.
We also can't provide a PaymentId for trampoline payments, which we'd like to, I think. We might also want to keep a separate routing trait for the payer? Ugh...
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.
It wouldn't be ideal to provide users with the payment hash in trampoline payments.
Do either of these options seem reasonable: (1) make payment_hash into an
Option<(PaymentHash, PaymentId)>
(2) make payment_hash into anOption<PaymentId>
Where is PaymentId
coming from / why is it needed?
I think it's leaking the sender's privacy since it's not our payment
Not really sure I follow this. If our node knows the payment hash, hasn't it already been leaked?
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.
IIUC there's still a difference in privacy between seeing it in an internal update_add_htlc
message vs actually providing it to a user in a trait method.
Where is PaymentId coming from / why is it needed?
Same reason a payment_hash
is being provided in 592bfd7 I think, to have another option to look up pre-computed probes. As of #1761, PaymentId
s will be required upon all payment initiations, so it'd come from there for non-trampoline find_route
calls.
lightning/src/ln/channelmanager.rs
Outdated
/// A map with liquidity value (in msat) keyed by a short channel id and the direction the HTLC | ||
/// is traveling in. The direction boolean is determined by checking if the HTLC source's public | ||
/// key is less than its destination. See [`InFlightHtlcs::used_liquidity_msat`] for more | ||
/// details. | ||
#[cfg(not(any(test, feature = "_test_utils")))] | ||
pub struct InFlightHtlcs(HashMap<(u64, bool), u64>); | ||
#[cfg(any(test, feature = "_test_utils"))] | ||
pub struct InFlightHtlcs(pub HashMap<(u64, bool), u64>); | ||
|
||
impl InFlightHtlcs { | ||
/// Create a new `InFlightHtlcs` via a mapping from: | ||
/// (short_channel_id, source_pubkey < target_pubkey) -> used_liquidity_msat | ||
pub fn new(inflight_map: HashMap<(u64, bool), u64>) -> Self { | ||
InFlightHtlcs(inflight_map) | ||
} |
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.
Maybe could be left to a later refactor (cc: @jurvis), but it seems odd we expose the implementation details about the HashMap
. Perhaps we should have a method for adding paths.
Another thought -- when adding this to the Payer
interface -- is to have an associated type with a trait bound on some new trait having a used_liquidity_msat
. Though that would mean Router
and Payer
would need to agree on that associated type as it would be need in Router
, too.
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.
It does seem like the best way here could depend on how #1157 shakes out. I agree it's weird but I'm not 100% sure the best approach that wouldn't churn. Open to @jurvis's and your thoughts though if there seems to be a clear way.
when adding this to the Payer interface
Not following, what is being added to Payer
?
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.
Not following, what is being added to
Payer
?
A method for accessing InFlightHtlcs
. Background: #1643 (comment)
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, I wouldn't be opposed to an associated type. I'm reluctant to be totally blocked on that issue though. Do you think there's something that can be done to make progress in the meantime here?
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.
I don't really understand why an associated type makes sense - what implementation other than a HashMap would someone want to use for this?
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.
Was leaning towards the former approach. Anyhow, this is orthogonal to the PR. Figured @jurvis would tackle it when updating the Payer
trait.
lightning/src/ln/channelmanager.rs
Outdated
/// Lets the router know that payment through a specific path has failed. | ||
fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64); | ||
/// Lets the router know that payment through a specific path was successful. | ||
fn notify_payment_path_successful(&self, path: &[&RouteHop]); |
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.
Will ChannelManager
need to care about these methods? Seems like the distinction isn't probing vs non-probing but rather routing vs event handling.
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.
ChannelManager
as an async sending LSP has an opportunity to collect a lot of useful payment success/failure data for scoring. That said, I'm ok leaving these methods out for now if it's preferred
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.
Hmm... so essentially ChannelManager
wouldn't surface any events for the user to handle but would handle them internally. Wouldn't it also need to retry failures? Seems like something more akin to InvoicePayer
would be required rather than just the Router
.
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.
Discussed offline, yes that's accurate but we're not sure what to do yet. W/r/t to the question at hand, would you prefer to remove these methods for now?
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.
Discussed offline, yes that's accurate but we're not sure what to do yet. W/r/t to the question at hand, would you prefer to remove these methods for now?
Yeah, let's remove them... But that said, should we even bother with the interface churn now -- given this is for experimentation -- if it will likely to be different when accounting for retires? That is, can't the experiment simply call the standalone find_route
function directly for now?
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.
Right, i'm definitely gonna remove the payment_path_*
methods for now. I was hoping to get your input on:
should we even bother with the interface churn now -- given this is for experimentation -- if it will likely to be different when accounting for retires? That is, can't the experiment simply call the standalone find_route function directly for now?
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.
I don't see why that changes anything? Yes, we'll want to provide the "previous path attempts" set to the router just like we do for regular payments, but that can come as a parameter (eg via RouteParameters, just like we do for our own payments).
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 concern is about essentially re-writing the retry logic of InvoicePayer
here. I'm not yet convinced parameterizing ChannelManager
with a Router
is the right approach. Even if it is, it sorta begs the question as to why we shouldn't move all of InvoicePayer
's retry logic inside ChannelManager
rather than using InvoicePayer
as an EventHandler
wrapper, as we currently do. Just think we need to put some more thought into this design.
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.
Ah, sorry, I thought you meant passing previous-try info into the Router. Right, I'd think we'd want to move the retry logic into the ChannelManager, though that seems independent, I dont think the Router trait would look any different once we move retry logic into ChannelManager, so this would still be a good first step.
Indeed, if we didnt want to move retrying into the ChannelManager
then we'd probably have this look very different, but the question there seems to me to be "do we want/expect every routing node to support trampoline, or is it really just an LSP-level thing". If we think its an LSP-level thing I think we shouldn't do trampoline at all (it has terrible privacy in that kind of deployment). If we think it should be a part of every routing node, then pushing the trampoline handling out to an event would force users into a good bit of boilerplate that they really have no choice but to implement, which seems wasteful.
Adding retry logic into ChannelManager also seems kinda nice, it simplifies the amount of boilerplate users have to have for handling their own payments, which we've heard is an issue for users, and its no less expressible - you can always pass a RetryCount(0)
when sending a payment and handle it yourself.
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.
Discussed offline, gonna move forward with parameterizing ChannelManager
with Router
but reassess overall API design at each step. There may be an opportunity to break ChannelManager
up into multiple subsystems (e.g. payment forwarding) to clean things up along the way.
@jkczyz can speak more to this, but it may be advantageous to create a Node
abstraction over InvoicePayer
/ ChannelManager
(which could be renamed).
8828fce
to
8b4fed2
Compare
lightning-invoice/src/payment.rs
Outdated
&self, payer: &PublicKey, route_params: &RouteParameters, payment_hash: &PaymentHash, | ||
&self, payer: &PublicKey, route_params: &RouteParameters, |
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.
It wouldn't be ideal to provide users with the payment hash in trampoline payments.
Do either of these options seem reasonable: (1) make payment_hash into an
Option<(PaymentHash, PaymentId)>
(2) make payment_hash into anOption<PaymentId>
Where is PaymentId
coming from / why is it needed?
I think it's leaking the sender's privacy since it's not our payment
Not really sure I follow this. If our node knows the payment hash, hasn't it already been leaked?
/// and scoring based on payment success data. | ||
/// | ||
/// [`Router`]: lightning::ln::channelmanager::Router | ||
pub trait ScoringRouter: Router { |
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.
Why don't we define a different find_route
function here that does include the PaymentId
/PaymentHash
and just call out to the underlying find_route
by default?
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.
Not sure I follow why we want to do this and why it shouldn't be on Router
instead. Doesn't look like it's used here?
d054b25
to
8ca062f
Compare
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.
Basically LGTM.
7db8052
to
df593dc
Compare
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.
Feel free to squash.
This is part of moving the Router trait into ChannelManager, which will help allow ChannelManager to fetch routes on-the-fly as part of supporting trampoline payments.
This helps prepare to parameterize ChannelManager with a Router, to eventually use in trampoline payments.
df593dc
to
9d33249
Compare
This prepares us to parameterize
ChannelManager
with aRouter
trait, which will then be used to fetch routes on-the-fly for trampoline payments.Relates to #1157 although trampoline is not blocked by it --
ChannelManager
can just not factor in in-flight HTLCs for now.