Skip to content

lnworker: pass PaySession to route building methods. #9623

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

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

accumulator
Copy link
Member

@accumulator accumulator commented Mar 10, 2025

Simplifies method signatures and groups quite a large set of parameters that are mostly passed down along the call stack but functionally belong together. Also removes bolt11 specific parameters in method signatures, e.g. r_tags, which are not relevant in e.g. a bolt12 context.

@accumulator accumulator force-pushed the pass_paysession_in_route_building branch from 6c9a520 to 7ac0b8f Compare March 10, 2025 14:10
@accumulator accumulator marked this pull request as ready for review March 10, 2025 14:30
@accumulator accumulator force-pushed the pass_paysession_in_route_building branch 2 times, most recently from af7c375 to 6f1099c Compare March 19, 2025 14:14
Simplifies method signatures and groups quite a large set of
parameters that are mostly passed down along the call stack but functionally belong together.
Also removes bolt11 specific parameters in method signatures, e.g. r_tags.
@accumulator accumulator force-pushed the pass_paysession_in_route_building branch from 6f1099c to 263b3e6 Compare March 20, 2025 07:55
min_final_cltv_delta=paysession.min_final_cltv_delta,
r_tags=paysession.r_tags,
invoice_features=paysession.invoice_features,
paysession=paysession,
Copy link
Member

Choose a reason for hiding this comment

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

Note that the fields of PaySession are mutable. We are passing them to a function that is run asynchronously (await run_in_thread). This happens to be fine in that case, because the fields we are passing (invoice_pubkey, invoice, r_tags, min_final_cltv_delta) happen to not be mutated during the lifetime of the session. However, this seems to be lucky. What would happen if we had been passing paysession._amount_inflight, or some other variable field? Then the value at the time it is evaluated in the coroutine might differ from the value passed as parameter.

Copy link
Member Author

Choose a reason for hiding this comment

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

We could store the relevant (immutable) fields in a NamedTuple within PaySession and pass that instead. This way there is no access to the mutable fields of PaySession in the routing methods

Copy link
Member

Choose a reason for hiding this comment

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

Note that the fields of PaySession are mutable

Good point.

store the relevant (immutable) fields in a NamedTuple within PaySession

(btw besides NamedTuple, there is also @dataclass(frozen=True) in the stdlib. It is similar to attrs, a tiny bit less flexible, but attrs I would eventually like to remove from the dependencies)

Copy link
Member Author

@accumulator accumulator Mar 20, 2025

Choose a reason for hiding this comment

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

(btw besides NamedTuple, there is also @dataclass(frozen=True) in the stdlib. It is similar to attrs, a tiny bit less flexible, but attrs I would eventually like to remove from the dependencies)

Yes I have looked at dataclasses, but this is too inflexible, as there are mutable fields in PaySession that should remain mutable in certain cases, and I haven't seen an option to selectively un-immute (heh) a subset of fields. Subclassing also doesn't allow mutability as the restriction propagates down the hierarchy.

Copy link
Member Author

@accumulator accumulator Mar 20, 2025

Choose a reason for hiding this comment

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

I added a method to return an immutable copy and pass that instead. See addcbc3

There's probably nicer ways to do this, e.g. externalize the __setattr__ override.

e.g. a generic method def immutable(object) that returns an immutable copy of the object

Copy link
Member Author

@accumulator accumulator Mar 20, 2025

Choose a reason for hiding this comment

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

Hmm.. I'm not really happy with the last commit. If we copy the PaySession it does not really need to be immutable, and the added code is.. not very nice.

Maybe it is nicer to add a NamedTuple within PaySession, and just pass that immutable tuple down to the routing functions. If anyone has a nice naming suggestion?

Copy link
Member

Choose a reason for hiding this comment

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

indeed I would prefer not to pass paysession to that method, but a namedtuple that can be a field of paysession.

The other call (create_trampoline_route_and_onion) needs to pass a mutable field (failed_trampoline_routes) in addition to immutable fields. That mutable field should be passed explicitly, in addition to the namedtuple.

Copy link
Member Author

@accumulator accumulator Mar 20, 2025

Choose a reason for hiding this comment

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

as I'm reworking the patch to pass a NamedTuple, it looks like there are too many exceptions to really benefit from this encapsulation :( (e.g. use_two_trampolines is mutable and part of PaySession, but must be passed explicitly to create_trampoline_route())

passing the NamedTuple and extra fields of PaySession along is not really an improvement of the old situation IMO.

Unless we find a more elegant solution, I propose to abandon this PR

@accumulator accumulator force-pushed the pass_paysession_in_route_building branch 2 times, most recently from 8aaa815 to d3d83b5 Compare March 20, 2025 11:26
@accumulator accumulator force-pushed the pass_paysession_in_route_building branch from d3d83b5 to addcbc3 Compare March 20, 2025 11:27
@accumulator accumulator marked this pull request as draft March 20, 2025 15:59
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