Skip to content

htlcswitch: add an always on mode to htlc interceptor#6232

Merged
guggero merged 2 commits intolightningnetwork:masterfrom
bottlepay:require-interceptor
Mar 19, 2022
Merged

htlcswitch: add an always on mode to htlc interceptor#6232
guggero merged 2 commits intolightningnetwork:masterfrom
bottlepay:require-interceptor

Conversation

@joostjager
Copy link
Contributor

@joostjager joostjager commented Feb 3, 2022

Adds a flag that makes htlc interception a requirement. The switch will queue htlcs as long as there is no interceptor connected. When the stream disconnects, htlcs waiting for resolution will not resume automatically.

Supersedes #6165

Solves #6161

Copy link
Contributor Author

@joostjager joostjager Feb 3, 2022

Choose a reason for hiding this comment

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

To prevent startup order issues, I think it is key to have this boolean here in the interceptable switch.

See also #6165 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Upon further inspection, it seems that linkQuit is not worth the hassle to thread through.

Copy link
Contributor

Choose a reason for hiding this comment

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

This effectively removes the feature entirely, doesn't it? Since packets always come through here. I'm not sure about the merits linkQuit has, or lacks, but it IMO this is not the PR to kill it or the way to do it. If desired, it should be removed completely from htlcSwitch rather than silently disused.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not killing it complicates matters because we also have the resume path to the switch. In current master, linkQuit is stored and may not be usable anymore when resume is called. I think that might be a bug.

I think it is indeed best to kill it completely, but first wanted to await review of the change. Probably going to cause a large but simple delta.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added commit deleting linkQuit.

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 also deleted a complicated test case TestChannelLinkShutdownDuringForward testing linkQuit. To me it seems that the case where the switch is completely blocked isn't realistic, but maybe someone with more context can weigh in.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

forwardInterceptor can be cleaned up a lot now that it doesn't need the synchronization anymore to manage the hold list.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the main change. holdForwards are now kept here. This prevents complexities with InterceptableSwitch and forwardInterceptor both trying to do things with held htlcs.

@joostjager joostjager requested a review from carlaKC February 3, 2022 15:31
@joostjager
Copy link
Contributor Author

@carlaKC @champo I tried a few variations of the always on interceptor and ended up with what's in this PR. Tried to address the outstanding comments in #6165

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Need to think how the onchain interception flow (#6219) can connect to this.

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 rebased #6219 to demonstrate how it can be done.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Height watching can happen in this loop as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Discussed offline that this will be a follow up PR

@joostjager joostjager force-pushed the require-interceptor branch 4 times, most recently from ae808b2 to 2499a6a Compare February 7, 2022 07:38
@joostjager joostjager changed the title refactor htlc interceptor htlcswitch: add an always on mode to htlc interceptor Feb 7, 2022
@joostjager joostjager marked this pull request as ready for review February 7, 2022 07:48
@joostjager joostjager force-pushed the require-interceptor branch 2 times, most recently from 390dc05 to 64580c5 Compare February 7, 2022 07:58
@joostjager joostjager removed the request for review from carlaKC February 7, 2022 08:15
@joostjager joostjager force-pushed the require-interceptor branch 3 times, most recently from cbe83d6 to d01e22f Compare February 7, 2022 08:54
@joostjager joostjager requested a review from carlaKC February 7, 2022 09:01
Copy link
Contributor

Choose a reason for hiding this comment

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

Why should an error here stop the loop? Feels like either LND should crash or carry on.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. Converted to log and carry on.

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I'd reference the comment on ForwardPackets below regarding linkQuit here

Comment on lines 190 to 191
Copy link
Contributor

Choose a reason for hiding this comment

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

given that s.intercepted is an unbuffered channel, doesn't this stop the switch processing completely? ForwardPackets would block on s.intercepted <- packets until an interceptor is registered. I checked the call sites to ForwardPackets and they are not ready for it to be a blocking call. In particular, it would block the links main loop which smells like it can trigger unwanted force closes (I'm clearly not an expert on that subsystem and I can certainly be wrong).

IMO interceptForward should be handling this by simply adding the packet to the map. The logic to re-send intercepted packets on setInterceptor would handle the rest when the intercept comes back up.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Excellent point. @carlaKC also expressed concerns about this blocking behavior.

Implemented your suggestion, which is indeed simpler and cleaner.

Copy link
Contributor

Choose a reason for hiding this comment

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

This effectively removes the feature entirely, doesn't it? Since packets always come through here. I'm not sure about the merits linkQuit has, or lacks, but it IMO this is not the PR to kill it or the way to do it. If desired, it should be removed completely from htlcSwitch rather than silently disused.

@champo
Copy link
Contributor

champo commented Feb 8, 2022

This is a great improvement! Moving the logic to interceptable switch makes a lot of sense.

Copy link
Collaborator

@carlaKC carlaKC left a comment

Choose a reason for hiding this comment

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

Great refactor and nice solution to the "always on" question.

Copy link
Contributor

Choose a reason for hiding this comment

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

shouldn't this pass the interceptable switch quit channel?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This code is no longer running on the link goroutine. The original reason was to prevent a deadlock with switch and link. I think the deadlock can't happen in this case.

@carlaKC carlaKC requested a review from yyforyongyu February 21, 2022 08:26
@lightninglabs-deploy
Copy link
Collaborator

@yyforyongyu: review reminder

@Roasbeef Roasbeef added bug fix htlcswitch P1 MUST be fixed or reviewed labels Mar 7, 2022
@Roasbeef Roasbeef modified the milestones: v0.16.0, v0.15.0 Mar 7, 2022
In this commit we move the tracking of the outstanding intercepted htlcs
to InterceptableSwitch. This is a preparation for making the htlc
interceptor required.

Required interception involves tracking outstanding htlcs across
multiple grpc client sessions. The per-session routerrpc
forwardInterceptor object is therefore no longer the best place for
that.
@joostjager joostjager force-pushed the require-interceptor branch 2 times, most recently from 01a3dac to 5c89c14 Compare March 15, 2022 07:54
@joostjager
Copy link
Contributor Author

Rebased

@bhandras bhandras requested review from bhandras and removed request for yyforyongyu March 16, 2022 14:59
@bhandras
Copy link
Collaborator

Taking over review from @yyforyongyu to balance his load a bit.


log.Infof("Interceptor disconnected, resolving held packets")

for _, fwd := range s.holdForwards {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is preexisting but looping through s.holdForwards may change the order of packets.

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. Do you think there is a point in guarantees about ordering? I am not sure to what extend order is maintained elsewhere. For example when update_add messages come in in the link. Also a replay from the on-chain flow to the interceptor (next pr) just cuts through whatever order there may have been.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Had to dig a bit deeper to fully understand how the forwarding works. There doesn't seem to be any risk in reordering since the interceptor sits right before the Switch.

Copy link
Collaborator

@bhandras bhandras left a comment

Choose a reason for hiding this comment

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

LGTM 🎉

Co-authored-by: Juan Pablo Civile <elementohb@gmail.com>
@joostjager joostjager force-pushed the require-interceptor branch from 5c89c14 to ae314ec Compare March 17, 2022 16:39
@joostjager
Copy link
Contributor Author

joostjager commented Mar 18, 2022

Who can hit the merge button on this triple green check pr? 🙏 There is more work to do within this theme! 🚀

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

Labels

bug fix htlcswitch P1 MUST be fixed or reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants