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

[2/?] Instant loop out: Add reservations #632

Merged
merged 13 commits into from
Jan 17, 2024

Conversation

sputn1ck
Copy link
Member

@sputn1ck sputn1ck commented Aug 25, 2023

Prior PR: #631

Skip 1st commit

This PR adds reservation functionality to loop.

Reservations are 2-of-2 musig2 taproot outputs with a single funder. The output contains an expiry path that allows the funder to spend the funds after N blocks.

Reservations can be used a new type of loop out, where the server commits funds to the 2-of-2 output and the loop client can then trustlessly and instantaneously loop out, allow for rapid rebalancing of channels.

The reservation state machine in this PR looks like this:

stateDiagram-v2
[*] --> Init: OnServerRequest
Confirmed
Confirmed --> TimedOut: OnTimedOut
Confirmed --> Confirmed: OnRecover
Failed
Init
Init --> Failed: OnError
Init --> WaitForConfirmation: OnBroadcast
Init --> Failed: OnRecover
TimedOut
WaitForConfirmation
WaitForConfirmation --> WaitForConfirmation: OnRecover
WaitForConfirmation --> Confirmed: OnConfirmed
WaitForConfirmation --> TimedOut: OnTimedOut
Loading

TODO:

  • SQL db
  • Recover reservation fsms on startup
  • More Unit test coverage

Next PR: #633

Copy link
Collaborator

@hieblmi hieblmi left a comment

Choose a reason for hiding this comment

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

This is great work @sputn1ck. I think future features will benefit from your code structure. I've just left a couple of things that sprung to my eye so far.

reservation/script.go Outdated Show resolved Hide resolved
reservation/script.go Outdated Show resolved Hide resolved
reservation/script.go Outdated Show resolved Hide resolved
reservation/actions.go Outdated Show resolved Hide resolved
reservation/actions.go Outdated Show resolved Hide resolved
loopd/daemon.go Outdated Show resolved Hide resolved
reservation/server.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@hieblmi hieblmi left a comment

Choose a reason for hiding this comment

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

Some more comments.

reservation/server.go Outdated Show resolved Hide resolved
reservation/manager.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@hieblmi hieblmi left a comment

Choose a reason for hiding this comment

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

Some more comments

reservation/manager.go Outdated Show resolved Hide resolved
reservation/interfaces.go Outdated Show resolved Hide resolved
@sputn1ck sputn1ck force-pushed the instantloopout_2 branch 2 times, most recently from a4dc78e to 76559c6 Compare September 14, 2023 11:41
@sputn1ck sputn1ck force-pushed the instantloopout_2 branch 3 times, most recently from 94f7293 to e561c00 Compare October 12, 2023 12:58
reservation/actions.go Outdated Show resolved Hide resolved
fsm/fsm.go Outdated Show resolved Hide resolved
@sputn1ck sputn1ck force-pushed the instantloopout_2 branch 2 times, most recently from 9f6f3ae to e9a477e Compare October 24, 2023 20:33
@sputn1ck sputn1ck marked this pull request as ready for review October 24, 2023 20:34
@sputn1ck sputn1ck force-pushed the instantloopout_2 branch 5 times, most recently from bed3fd0 to b6a3924 Compare October 25, 2023 21:33
Copy link
Member

@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.

Excellent work, I added some comments, most of them are nits. Almost ready!

fsm/fsm.go Outdated Show resolved Hide resolved
fsm/fsm.go Outdated Show resolved Hide resolved
fsm/fsm.go Outdated
@@ -117,10 +126,42 @@ type StateMachine struct {
}

// NewStateMachine creates a new state machine.
func NewStateMachine(states States) *StateMachine {
func NewStateMachine(states States,
withoutDefaultObserver ...bool) *StateMachine {
Copy link
Member

Choose a reason for hiding this comment

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

What's the use for the variadic argument? If it is to avoid having an arg sometimes but being able to define it other times, then I'd recommend just keeping it as a normal arg for better readability.

Copy link
Member

Choose a reason for hiding this comment

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

Another cleaner way is to use an option modifier type instead.

fsm/fsm.go Outdated Show resolved Hide resolved
fsm/fsm.go Outdated
var defaultObserver *CachedObserver

if len(withoutDefaultObserver) == 0 || !withoutDefaultObserver[0] {
defaultObserver = NewCachedObserver(100)
Copy link
Member

Choose a reason for hiding this comment

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

Can you add a comment why this is useful? Also is 100 just a magic large number or need to be specifically this high?

Copy link
Member Author

Choose a reason for hiding this comment

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

100 is just a magic large number. do you have a recommendation?

Copy link
Member Author

Choose a reason for hiding this comment

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

changed it to pass on a single int for the observer size

reservation/manager.go Outdated Show resolved Hide resolved
go func() {
for {
select {
case <-ctx.Done():
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this goroutine (and this whole function) use the m.runCtx instead?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this would be correct if the passed in ctx here was m.runCtx. RegisterReservationNotifications is called in Run().

Copy link
Member Author

Choose a reason for hiding this comment

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

Shouldn't this goroutine (and this whole function) use the m.runCtx instead?

I don't think so, as we can return if the client cancels the stream. There would be no more channel to send to

reservation/manager.go Outdated Show resolved Hide resolved
reservation/manager.go Outdated Show resolved Hide resolved
loopd/daemon.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@hieblmi hieblmi left a comment

Choose a reason for hiding this comment

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

Awesome work @sputn1ck, this is looking really good. I've left more code design and style nits this time and also have some clarifying questions.

cmd/loop/reservations.go Show resolved Hide resolved
loopd/daemon.go Outdated Show resolved Hide resolved
loopd/swapclient_server.go Outdated Show resolved Hide resolved
loopd/swapclient_server.go Outdated Show resolved Hide resolved
loopd/swapclient_server.go Outdated Show resolved Hide resolved
reservation/fsm.go Outdated Show resolved Hide resolved
reservation/fsm.go Outdated Show resolved Hide resolved
reservation/interfaces.go Outdated Show resolved Hide resolved
reservation/interfaces.go Outdated Show resolved Hide resolved
reservation/interfaces.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@hieblmi hieblmi left a comment

Choose a reason for hiding this comment

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

Great work @sputn1ck!


// Create the reservation state machine. We need to pass in the runCtx
// of the reservation manager so that the state machine will keep on
// running even if the grpc conte
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: incomplete comment

This commit adds the reservation state machine and actions to the
reservation package.
@sputn1ck sputn1ck force-pushed the instantloopout_2 branch 2 times, most recently from cdf68b2 to eebf8bb Compare January 17, 2024 14:12
@sputn1ck sputn1ck force-pushed the instantloopout_2 branch 2 times, most recently from 6fdaaa4 to 19176d4 Compare January 17, 2024 14:49
Copy link
Member

@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.

Re-reviewed due to added test coverage. LGTM 🎉 🎉

instantout/reservation/actions_test.go Outdated Show resolved Hide resolved
@sputn1ck sputn1ck merged commit e9d374a into lightninglabs:master Jan 17, 2024
4 checks passed
@sputn1ck sputn1ck deleted the instantloopout_2 branch January 17, 2024 15:02
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.

4 participants