-
Notifications
You must be signed in to change notification settings - Fork 2.3k
htlcswitch+invoices: allow settling invoices via multi-path payments #3415
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| package invoices | ||
|
joostjager marked this conversation as resolved.
Outdated
|
||
|
|
||
| import ( | ||
| "sync" | ||
| "time" | ||
| ) | ||
|
|
||
| // testClock can be used in tests to mock time. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Really nice! May I suggest you to extend
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't want to delay this PR with a discussion on where to put that package/file. Given the time those took in past prs I'd rather avoid it (reference class forecasting). |
||
| type testClock struct { | ||
| currentTime time.Time | ||
| timeChanMap map[time.Time][]chan time.Time | ||
| timeLock sync.Mutex | ||
| } | ||
|
|
||
| // newTestClock returns a new test clock. | ||
| func newTestClock(startTime time.Time) *testClock { | ||
| return &testClock{ | ||
| currentTime: startTime, | ||
| timeChanMap: make(map[time.Time][]chan time.Time), | ||
| } | ||
| } | ||
|
|
||
| // now returns the current (test) time. | ||
| func (c *testClock) now() time.Time { | ||
| c.timeLock.Lock() | ||
| defer c.timeLock.Unlock() | ||
|
|
||
| return c.currentTime | ||
| } | ||
|
|
||
| // tickAfter returns a channel that will receive a tick at the specified time. | ||
| func (c *testClock) tickAfter(duration time.Duration) <-chan time.Time { | ||
| c.timeLock.Lock() | ||
| defer c.timeLock.Unlock() | ||
|
|
||
| triggerTime := c.currentTime.Add(duration) | ||
| log.Debugf("tickAfter called: duration=%v, trigger_time=%v", | ||
| duration, triggerTime) | ||
|
|
||
| ch := make(chan time.Time, 1) | ||
|
|
||
| // If already expired, tick immediately. | ||
| if !triggerTime.After(c.currentTime) { | ||
| ch <- c.currentTime | ||
| return ch | ||
| } | ||
|
|
||
| // Otherwise store the channel until the trigger time is there. | ||
| chans := c.timeChanMap[triggerTime] | ||
| chans = append(chans, ch) | ||
| c.timeChanMap[triggerTime] = chans | ||
|
|
||
| return ch | ||
| } | ||
|
|
||
| // setTime sets the (test) time and triggers tick channels when they expire. | ||
| func (c *testClock) setTime(now time.Time) { | ||
| c.timeLock.Lock() | ||
| defer c.timeLock.Unlock() | ||
|
|
||
| c.currentTime = now | ||
| remainingChans := make(map[time.Time][]chan time.Time) | ||
| for triggerTime, chans := range c.timeChanMap { | ||
| // If the trigger time is still in the future, keep this channel | ||
| // in the channel map for later. | ||
| if triggerTime.After(now) { | ||
| remainingChans[triggerTime] = chans | ||
| continue | ||
| } | ||
|
|
||
| for _, c := range chans { | ||
| c <- now | ||
| } | ||
| } | ||
|
|
||
| c.timeChanMap = remainingChans | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.