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

htlcswitch: sync local payment hand-off to link #4183

Merged
merged 10 commits into from
May 20, 2020

Conversation

joostjager
Copy link
Contributor

@joostjager joostjager commented Apr 13, 2020

This PR converts the switch and link to synchronous hand-off of local payments.

Tried it out on the mpp send payment itest. To make sure that the async hand-off would lead to an extra payment attempt, I added a 100 ms sleep in the link before adding the htlc to the channel.

This is the original timing diagram, which shows the temp. chan failure originating from ourselves (@ 0)

image

With sync hand-off, it looks like this:

image

Fixes #4181

@joostjager
Copy link
Contributor Author

joostjager commented Apr 13, 2020

Current problem is that the link balance isn't yet updated after channel.AddHtlc has been called.

Faulty analysis. Nothing wrong with calculating the balance, I just printed the wrong number.

@joostjager
Copy link
Contributor Author

No attention paid to unit tests and itests yet. Looking for a concept ack.

@joostjager
Copy link
Contributor Author

Wondering if there is a good reason to pass local sends through the event loop?

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.

Of the options in # #4181, I prefer synchronous handoff to creating some workaround which tries to track pending balance deltas; that feels messy. There are always tradeoffs when making changes in the switch of course, but I think this change moves in the direction of less complexity, which I like a lot.

Not critical, but might also be worth thinking about how this would interact with an interceptor (eg #4018), since that is on the table for 0.11, if we do go ahead with this approach.

htlcswitch/switch.go Outdated Show resolved Hide resolved
htlcswitch/switch.go Show resolved Hide resolved
htlcswitch/switch.go Outdated Show resolved Hide resolved
htlcswitch/interfaces.go Outdated Show resolved Hide resolved
@joostjager joostjager removed the request for review from Roasbeef April 28, 2020 07:25
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.

Nice changes, concept ACK from me. Should be gg after addressing carla's comments

htlcswitch/link.go Outdated Show resolved Hide resolved
hodlQueue: queue.NewConcurrentQueue(10),
log: build.NewPrefixLog(logPrefix, log),
quit: make(chan struct{}),
downstreamIn: make(chan *downstreamMsg),
Copy link
Contributor

Choose a reason for hiding this comment

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

group with other downstream chnanel

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the other downstream chan isn't initialized here

@Crypt-iQ
Copy link
Collaborator

Crypt-iQ commented May 2, 2020

Solid set of changes, the way you changed the switch was straightforward and actually reduced complexity. Before I read through the changes, I was worried there would be more complexity. LGTM upon travis pass

@joostjager
Copy link
Contributor Author

Not critical, but might also be worth thinking about how this would interact with an interceptor (eg #4018), since that is on the table for 0.11, if we do go ahead with this approach.

@carlaKC I think the interceptor skips local payments.

@joostjager joostjager force-pushed the sync-local-payment branch 2 times, most recently from 2726fcd to 38e1a94 Compare May 6, 2020 14:44
@joostjager
Copy link
Contributor Author

Todo: itest fails because link does not cancel back local htlcs when commitment is full

@joostjager
Copy link
Contributor Author

joostjager commented May 13, 2020

itest is now stuck on sphinx_replay_persistence

Makes sense because it relies on the mailbox to simulate resending of a packet. Maybe it is an option to modify the test to use three hops.

Anyone suggestions on more direct ways to force a replay?

Move creation of the goroutine as a preparation for sync local routing
@joostjager joostjager force-pushed the sync-local-payment branch 3 times, most recently from 4893eca to ab2bb78 Compare May 14, 2020 09:25
@joostjager
Copy link
Contributor Author

Integration test fixed

htlcswitch/switch_test.go Outdated Show resolved Hide resolved
l.log.Tracef("received switch packet outkey=%v", pkt.outKey())

// Create a buffered result channel to prevent the link from blocking.
errChan := make(chan error, 1)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are we buffering this to account for the case where the link gets a shutdown instruction and stops listening, or to account for the time between this function sending and starting to listen?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the former. If this function HandleLocalAddPacket quits, the link event loop can't deliver the message anymore.

htlcswitch/switch.go Show resolved Hide resolved
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 📊

htlcswitch/link.go Outdated Show resolved Hide resolved
Previously the forward(...) method was used in forwarding tests,
while that code path isn't used for forwards in reality.
Embed forward method into SendHTLC and remove redundant type check.
There is no concurrent access in this code path, so there is no need to
pass the call through the main event loop.
Deduplicate code and prepare for further split of
handleDownstreamPkt.
Unroll common code to allow splitting in separate handlers per message
type.
To be able to call just the UpdateAdd logic for synchronously handled
local adds in a later commit.
This commit extends the link with a new synchronous delivery point for
local UpdateAddHTLC messages. The switch method SendHTLC is updated to
use this delivery point and thereby becomes a synchronous call.

For MPP payments, synchronous hand-off is important. Otherwise the next
pathfinding round could start without the channel balance updated yet.
Fixes a pre-existing issue where nil was returned when a failure had
occurred during commiting of the circuit.
Align function name with the contained logic.
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! Nice to see those refactors bundled in here that make the logic overall more readable 🔥

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 change, really improves readability of this area. LGTM!

@Roasbeef
Copy link
Member

Roasbeef commented May 3, 2022

Potential unintended consequence of this change: #6485

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

Successfully merging this pull request may close these issues.

routing: pathfind with up-to-date bandwidth hints
5 participants