Inject clocks into swap lifecycle and update swap tests#1091
Inject clocks into swap lifecycle and update swap tests#1091hieblmi merged 3 commits intolightninglabs:masterfrom
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request refactors the time-related dependencies within the swap lifecycle to use an injectable clock. This significantly improves the testability and reliability of the swap logic by decoupling it from the system's real-time clock, allowing for more controlled and predictable execution in test environments and consistent behavior in production. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request effectively refactors the swap lifecycle to use an injected clock.Clock, removing direct dependencies on time.Now() and time.Since(). This is a great improvement for testability and makes the code more robust. The changes in production code are clean and correct.
My main feedback is on the test files. While some tests were updated to use a fixed time, many still use time.Now() when creating a TestClock. This can lead to flaky or non-deterministic tests. For consistency and to ensure test reliability, I've suggested using a fixed timestamp across all test files.
Note: Security Review is unavailable for this PR.
Add DepositConfirmationStatus and InsufficientConfirmationsDetails messages to support structured error responses when deposits lack sufficient confirmations for dynamic risk requirements.
Reduce MinConfs from 6 to 3 to allow faster swap attempts while the server enforces risk-based confirmation requirements. Update SelectDeposits to prioritize more-confirmed deposits first, increasing the likelihood of server acceptance. Add client-side logging of insufficient confirmation details from server error responses.
|
@claude review this |
|
Code Review for PR 1091 - Inject clocks into swap lifecycle Overall this is a clean and well-scoped refactor that improves testability by injecting a clock.Clock into the swap lifecycle. POSITIVE ASPECTS
ISSUES
In swap.go:newSwapConfig and loopout.go:Resume, the parameter is named 'clock', which shadows the 'clock' package import within the function body. While harmless here, it is a Go anti-pattern that can cause confusing compile errors if the function is ever extended. Convention is typically to use 'clk' or 'swapClock'. Same applies to the Resume function signature in loopout.go.
newSwapConfig accepts a clock.Clock with no nil check. If a caller passes nil, the first s.clock.Now() call will panic. Consider defaulting to clock.NewDefaultClock() when nil is passed, or documenting that the parameter must not be nil.
testLoopOutPaymentParameters now asserts swap.InitiationTime == startTime. There is no equivalent assertion for the loop-in path (e.g., in testLoopInSuccess). Adding a parallel check would complete the coverage symmetry and prevent the loop-in clock path from silently regressing.
Every test file uses clock.NewTestClock(time.Unix(123, 0)) without any comment. A brief comment or a shared package-level constant would improve readability. The named variable startTime pattern used in testLoopOutPaymentParameters should be followed at the other test sites too.
startTs := time.Now() measures migration wall-clock duration for a log line, which is likely intentional and out of scope here. A brief comment clarifying intent would prevent a future reader from flagging it as an oversight. MINOR NIT The resumeManager.clock field is only used in resumeLoopOutPayment. A comment noting that it is not propagated into the swap config (clock injection for the resumeSwaps path happens separately in client.resumeSwaps) would reduce future confusion about why two separate clock injection points exist. SUMMARY The core change is correct and the test coverage improvement is welcome. The main items worth addressing before merge are the parameter-name shadowing (item 1) and the missing nil guard (item 2). The rest are suggestions to improve clarity and test parity. |
starius
left a comment
There was a problem hiding this comment.
LGTM! 🚀
Please fix compilation of each commit. Maybe just squash them into a single commit.
| func newSwapConfig(lnd *lndclient.LndServices, store loopdb.SwapStore, | ||
| server swapServerClient, assets *assets.TapdClient) *swapConfig { | ||
| server swapServerClient, assets *assets.TapdClient, | ||
| clock clock.Clock) *swapConfig { |
There was a problem hiding this comment.
The first commit does not compile:
./loopin_test.go:50:68: not enough arguments in call to newSwapConfig
Please make sure each commit compiles and passes tests.
loopin_test.go
Outdated
| cfg := newSwapConfig(&ctx.lnd.LndServices, ctx.store, ctx.server, nil) | ||
| cfg := newSwapConfig( | ||
| &ctx.lnd.LndServices, ctx.store, ctx.server, nil, | ||
| clock.NewTestClock(time.Unix(123, 0)), |
There was a problem hiding this comment.
Shouldn't we add a similar check as in loopout_test.go? That the time comes from the clock:
require.Equal(t, startTime, swap.InitiationTime)Inject clock.Clock into swapConfig so that swap initiation times are deterministic and testable. Update all swap tests to use TestClock with a fixed time, and assert that InitiationTime matches the clock value.
This PR threads an injected
clock.Clockthrough swap setup and resume paths so swap timestamps and duration accounting no longer depend directly ontime.Now()/time.Since().It also updates the affected tests to provide test clocks explicitly and adds coverage to ensure loop-out initiation timestamps use the injected clock.