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

Loop Out Sweep Batcher #634

Merged
merged 13 commits into from
Jan 23, 2024
Merged

Conversation

GeorgeTsagk
Copy link
Member

@GeorgeTsagk GeorgeTsagk commented Aug 26, 2023

Description

This PR adds a batcher for loop out htlc sweeps.

ToDo

  • Tx crafting & rbf strategy
  • Re-org safety

Also closes #675, this change was required due to the increased demands from our mocking interfaces with the introduction of the sweepbatcher

@GeorgeTsagk GeorgeTsagk self-assigned this Aug 26, 2023
@bhandras bhandras self-requested a review August 29, 2023 13:43
Copy link
Member

@sputn1ck sputn1ck left a comment

Choose a reason for hiding this comment

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

Did a first pass. As far as I can understand it it seems like an elegant approach.

However I'm not sure if the batcher is restart safe. E.g. what would happen if we have an inflight batch and restart loop. If no RBF of 'new' (but already broadcasted) sweeps would be braodcasted, would the confirmation logic be able to handle that?

batcher/sweep_batch.go Outdated Show resolved Hide resolved
batcher/sweep_batch.go Outdated Show resolved Hide resolved
batcher/sweep_batch.go Outdated Show resolved Hide resolved
batcher/sweep_batch.go Outdated Show resolved Hide resolved
@GeorgeTsagk GeorgeTsagk force-pushed the sweep-batcher branch 4 times, most recently from ac3d79e to 2f3bce1 Compare September 15, 2023 18:52
@GeorgeTsagk GeorgeTsagk marked this pull request as ready for review September 15, 2023 18:53
@GeorgeTsagk GeorgeTsagk force-pushed the sweep-batcher branch 5 times, most recently from 95938d0 to fc13d50 Compare September 22, 2023 09:42
@GeorgeTsagk GeorgeTsagk force-pushed the sweep-batcher branch 2 times, most recently from f5fc60f to 3adf5aa Compare September 25, 2023 16:06
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.

Really great work @GeorgeTsagk, your code comments help reviewing this PR. I will go over the functionality of this PR again more throughly - so far I got nits and questions for you :D

batcher/sweep_batcher.go Outdated Show resolved Hide resolved
batcher/sweep_batch.go Outdated Show resolved Hide resolved
batcher/sweep_batch.go Outdated Show resolved Hide resolved
batcher/sweep_batch.go Outdated Show resolved Hide resolved
batcher/sweep_batch.go Outdated Show resolved Hide resolved
batcher/sweep_batcher.go Outdated Show resolved Hide resolved
batcher/sweep_batcher.go Outdated Show resolved Hide resolved
batcher/sweep_batcher.go Outdated Show resolved Hide resolved
swap_server_client.go Show resolved Hide resolved
loopout.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.

Added some more comments but will hold back with further review until design Qs are ironed out.

loopdb/sqlc/migrations/000003_sweep_batcher.up.sql Outdated Show resolved Hide resolved
loopdb/sqlc/migrations/000003_sweep_batcher.down.sql Outdated Show resolved Hide resolved
batcher/sweep_batcher.go Outdated Show resolved Hide resolved
batcher/sweep_batch.go Outdated Show resolved Hide resolved
@GeorgeTsagk
Copy link
Member Author

There was a slight overhaul on the persistence aspect of batches. As suggested by @bhandras & @sputn1ck we now store all the sweeps that belong to a batch and do not wait for the swap to be resumed in order for their sweeps to be batched again.

@GeorgeTsagk GeorgeTsagk requested a review from hieblmi October 10, 2023 15:52
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.

Partial review, more is coming.

loopdb/batch.go Outdated Show resolved Hide resolved
loopdb/batch.go Outdated
ID int32

// BatchID is the ID of the batch that the sweep belongs to.
BatchID lntypes.Hash
Copy link
Member

Choose a reason for hiding this comment

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

Why not store a slice of sweeps in the Batch object instead?

Copy link
Member

Choose a reason for hiding this comment

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

Still applies.

Copy link
Member Author

@GeorgeTsagk GeorgeTsagk Nov 13, 2023

Choose a reason for hiding this comment

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

Since we're storing sweeps in their own table it seems simpler to me to separate them in the loopdb models.
In the application level (sweepbatcher pkg) sweeps are indeed stored within a batch

Copy link
Member

Choose a reason for hiding this comment

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

Reflecting the database scheme on the application level will add complexity to the application code. I advise not doing so.

Copy link
Member Author

@GeorgeTsagk GeorgeTsagk Nov 14, 2023

Choose a reason for hiding this comment

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

In the application level (sweepbatcher pkg) sweeps are indeed stored within a batch

I think this aligns with what you just said.

I am only keeping batches/sweeps separate in the loopdb level (I consider loopdb to not be application code..?)

loopdb/interface.go Outdated Show resolved Hide resolved
loopdb/interface.go Outdated Show resolved Hide resolved
loopdb/batch.go Outdated Show resolved Hide resolved
batcher/sweep_batcher.go Outdated Show resolved Hide resolved
batcher/sweep_batcher.go Outdated Show resolved Hide resolved
batcher/sweep_batch.go Outdated Show resolved Hide resolved
Value: int64(batchAmt - fee),
})

packet, err := psbt.NewFromUnsignedTx(batchTx)
Copy link
Member

Choose a reason for hiding this comment

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

I think we'd also need to sort the inputs and outputs to conform to BIP-69. AFAICT psbt lib doesn't do that.

txsort.InPlaceSort(batchTx)

Copy link
Member

Choose a reason for hiding this comment

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

This is still an issue.

Copy link
Member

Choose a reason for hiding this comment

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

Was this discussed offline? Marked as resolved but can't find the sorting

batcher/sweep_batch.go Outdated Show resolved Hide resolved
@GeorgeTsagk
Copy link
Member Author

Ty for the review @bhandras

Just pushed some changes, mostly affecting test files

@GeorgeTsagk GeorgeTsagk force-pushed the sweep-batcher branch 2 times, most recently from 1a71384 to b910c03 Compare October 30, 2023 11:29
@GeorgeTsagk GeorgeTsagk requested a review from sputn1ck January 18, 2024 14:36
@GeorgeTsagk GeorgeTsagk force-pushed the sweep-batcher branch 2 times, most recently from 85580fb to 53129d2 Compare January 18, 2024 17:23
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.

Getting close, great work on this last push!

sweepbatcher/sweep_batch.go Show resolved Hide resolved
sweepbatcher/sweep_batch.go Outdated Show resolved Hide resolved
sweepbatcher/sweep_batch.go Outdated Show resolved Hide resolved
sweepbatcher/sweep_batch.go Show resolved Hide resolved
sweepbatcher/sweep_batch.go Show resolved Hide resolved
sweepbatcher/sweep_batcher.go Outdated Show resolved Hide resolved
sweepbatcher/sweep_batcher.go Outdated Show resolved Hide resolved
sweepbatcher/sweep_batcher.go Show resolved Hide resolved
executor.go Outdated
@@ -121,6 +125,20 @@ func (s *executor) run(mainCtx context.Context,
return mainCtx.Err()
}

batcherErrChan = make(chan error, 1)
batcherCtx, cancel := context.WithCancel(mainCtx)
Copy link
Member

Choose a reason for hiding this comment

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

So what I meant is that it's fine to just call s.batcher.Run(mainCtx).

loopout.go Outdated Show resolved Hide resolved
@GeorgeTsagk GeorgeTsagk force-pushed the sweep-batcher branch 3 times, most recently from 0fc4e68 to fec3c5c Compare January 19, 2024 16:08
@GeorgeTsagk GeorgeTsagk requested a review from bhandras January 19, 2024 16:11
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.

Looks ripe! Nice work @GeorgeTsagk 🥇
A few last nits from my side.

sweepbatcher/sweep_batch.go Show resolved Hide resolved
sweepbatcher/sweep_batch.go Outdated Show resolved Hide resolved
sweepbatcher/sweep_batch.go Outdated Show resolved Hide resolved
sweepbatcher/sweep_batcher.go Outdated Show resolved Hide resolved
sweepbatcher/sweep_batcher.go Outdated Show resolved Hide resolved
loopout_test.go Outdated Show resolved Hide resolved
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.

LGTM, great work @GeorgeTsagk ⚡ ⚡

case <-ctx.Done():
}

_ = b.writeToErrChan(ctx, err)
Copy link
Member

Choose a reason for hiding this comment

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

q: Do we need to add this error to the batcher's error channel? It'll stop the batcher altogether.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, not sure. If we don't it will only fail on the batch/swap level. One reason to error out the whole daemon is that a restart may fix the monitor spend issue. But that could also "deadlock" the whole daemon just for the sake of 1 swap

Copy link
Member

@sputn1ck sputn1ck left a comment

Choose a reason for hiding this comment

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

LGTM! Congrats on the big PR.

I have a small set of nits that would be nice to haves.

loopdb/sql_store.go Outdated Show resolved Hide resolved
sweepbatcher/sweep_batch.go Show resolved Hide resolved

// If the provided sweep is nil, we can't proceed with any checks, so
// we just return early.
if sweep == nil {
Copy link
Member

Choose a reason for hiding this comment

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

why could a sweep be nil?

Copy link
Member Author

Choose a reason for hiding this comment

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

idk, always nice to check?

// To be sure that we're good, parse and validate that the
// combined signature is indeed valid for the sig hash and the
// internal pubkey.
err = b.verifySchnorrSig(
Copy link
Member

Choose a reason for hiding this comment

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

nit: combine sigs already checks if the sig is valid. removing the b.verifySchnorrSig part removes some code in this PR so i deem it worthy to remove.

See https://github.com/btcsuite/btcd/blob/master/btcec/schnorr/musig2/context.go#L650, which is called from https://github.com/lightningnetwork/lnd/blob/7d03b43ddfa11674a5002b4ecb5516ccc99f5303/input/musig2.go#L510

@@ -162,27 +164,36 @@ func NewClient(dbDir string, loopDB loopdb.SwapStore,
Lnd: cfg.Lnd,
}

verifySchnorrSig := func(pubKey *btcec.PublicKey, hash, sig []byte) error {
Copy link
Member

Choose a reason for hiding this comment

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

this could be removed, as we verify the sig when combining.

@alexbosworth
Copy link
Member

does this need a release notes comment?

@alexbosworth
Copy link
Member

any readme notes needed on config settings?

@GeorgeTsagk GeorgeTsagk merged commit df2db80 into lightninglabs:master Jan 23, 2024
4 checks passed
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.

Enhance LND mocking interface to support multiple subscribers
6 participants