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

sweepbatcher: add options WithInitialDelay and WithPublishDelay #801

Merged
merged 7 commits into from
Aug 13, 2024

Conversation

starius
Copy link
Collaborator

@starius starius commented Jul 31, 2024

WithInitialDelay instructs sweepbatcher to wait for the duration provided after new batch creation before it is first published. This facilitates better grouping. It only affects newly created batches, not batches loaded from DB, so publishing does happen in case of a daemon restart (especially important in case of a crashloop). Defaults to 0s. If a sweep is about to expire (time until timeout is less that 2x initialDelay), then waiting is skipped.

WithPublishDelay sets the delay of batch publishing that is applied in the beginning, after the appearance of a new block in the network or after the end of initial delay (see WithInitialDelay). It is needed to prevent unnecessary transaction publishments when a spend is detected on that block. Default value depends on the network: 5 seconds in mainnet, 0.5s in testnet. For batches recovered from DB this value is always 0s.

Also tested both options, in particular tested:

  • for a regular sweep newly added it waits for initialDelay + publishDelay before publishing a transaction
  • for a sweep recovered from DB it does not wait before publishing a transaction
  • if a sweep is about to expire, initialDelay is skipped

Pull Request Checklist

  • Update release_notes.md if your PR contains major features, breaking changes or bugfixes

@starius starius marked this pull request as ready for review July 31, 2024 17:27
@starius starius marked this pull request as draft July 31, 2024 17:30
@starius starius force-pushed the sweepbatcher-wait branch 3 times, most recently from 3d84565 to 40a9e29 Compare July 31, 2024 19:04
@starius starius marked this pull request as ready for review July 31, 2024 19:14
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 🎉 Added a few nits and comments to consider.

sweepbatcher/sweep_batch.go Outdated Show resolved Hide resolved
// skipBefore is the time before which we skip batch publishing.
// This is needed to facilitate better grouping of sweeps.
// For batches loaded from DB waitingPeriod should be 0.
skipBefore := time.Now().Add(b.cfg.waitingPeriod)
Copy link
Member

Choose a reason for hiding this comment

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

nit: instead of using real time, we could adopt the lnc/clock package so we can simulate time better in tests as needed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done. I added this in a separate commit "sweepbatcher: use lnd/clock for timers".

While updating the test, I found that the batch starts empty and then the first sweep is added. This results in the order of RegisterSpendNtfn and timer registrations being nondeterministic. I decided to catch this in the test via two separate goroutines to avoid deadlocks. Maybe the batch can be reworked in the future make sure it always calls RegisterSpendNtfn before starting any timers, then the code of the test can be simplified.

Testing for urgent batch failed sometimes, because the check happen to run before addSweep and the batch was empty at that point (timeout unknown). To fix this, the check was moved to timerChan handler, just before the code that checks if waiting period has ended, before publishing. By that time the sweep is added.

Also I found that lnd/clock is imported and stored as a field in store.go, but not used. I removed it in a separate commit.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe the batch can be reworked in the future make sure it always calls RegisterSpendNtfn before starting any timers, then the code of the test can be simplified.

Agreed!

sweepbatcher/sweep_batcher.go Outdated Show resolved Hide resolved
sweepbatcher/sweep_batcher.go Show resolved Hide resolved
test/timeout.go 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 @starius, I left a couple of nits and one cr.

sweepbatcher/sweep_batch.go Outdated 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 Outdated Show resolved Hide resolved
sweepbatcher/sweep_batcher.go Outdated Show resolved Hide resolved
sweepbatcher/sweep_batcher_test.go Outdated Show resolved Hide resolved
sweepbatcher/sweep_batcher_test.go Outdated Show resolved Hide resolved
sweepbatcher/sweep_batcher_test.go Outdated Show resolved Hide resolved
sweepbatcher/sweep_batcher_test.go Outdated Show resolved Hide resolved
sweepbatcher/sweep_batcher_test.go Show resolved Hide resolved
@starius starius changed the title sweepbatcher: add options WithWaitingPeriod and WithPublishDelay sweepbatcher: add options WithInitialDelay and WithPublishDelay Aug 9, 2024
@starius starius requested a review from hieblmi August 9, 2024 21:42
@starius
Copy link
Collaborator Author

starius commented Aug 9, 2024

@bhandras @hieblmi Please take another look!

I reworked commit structure to make it more reviewer friendly. First added lnd/clock, then the options, finally the test.

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 🥇


startTime := time.Date(2018, 11, 1, 0, 0, 0, 0, time.UTC)
tickSignal := make(chan time.Duration)
testClock := clock.NewTestClockWithTickSignal(startTime, tickSignal)
Copy link
Member

Choose a reason for hiding this comment

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

🎉

wg.Wait()

// Make sure the batcher exited without an error.
checkBatcherError(t, runErr)
Copy link
Member

Choose a reason for hiding this comment

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

Super nice test!

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.

Thanks for the fixes, LGTM💾

Renamed defaultPublishDelay to defaultTestnetPublishDelay. Its godoc was already
for defaultTestnetPublishDelay, but the const was named defaultPublishDelay.
Added option: WithClock. Use it for publishDelay timer.
It will be used for testing.
WithInitialDelay instructs sweepbatcher to wait for the duration provided
after new batch creation before it is first published. This facilitates
better grouping. It only affects newly created batches, not batches loaded from
DB, so publishing does happen in case of a daemon restart (especially important
in case of a crashloop). Defaults to 0s. If a sweep is about to expire (time
until timeout is less that 2x initialDelay), then waiting is skipped.
WithPublishDelay sets the delay of batch publishing that is applied in the
beginning, after the appearance of a new block in the network or after the
end of initial delay (see WithInitialDelay). It is needed to prevent
unnecessary transaction publishments when a spend is detected on that block.
Default value depends on the network: 5 seconds in mainnet, 0.5s in testnet.
For batches recovered from DB this value is always 0s.
@starius
Copy link
Collaborator Author

starius commented Aug 13, 2024

Rebased

Tested scenarios:

1. For a regular sweep newly added it waits for initialDelay + publishDelay
   before publishing a transaction.
2. For a sweep recovered from DB it does not wait before publishing tx.
3. If a sweep is about to expire, initialDelay is skipped.
@starius
Copy link
Collaborator Author

starius commented Aug 13, 2024

Fixed flakiness in new test. Fixed the code waiting for new sweep being added.

@starius starius merged commit 98fa740 into lightninglabs:master Aug 13, 2024
4 checks passed
@starius starius deleted the sweepbatcher-wait branch August 13, 2024 13:34
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