lightninglabs / lightninglabs/aperture
freebie: make quota consumption atomic and concurrency-safe
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 268
- Forks
- 78
- Avg merge
- 22h 25m
- Merged PRs (30d)
- 1
Description
## Summary
Freebie admission currently calls `DB.CanPass` and `DB.TallyFreebie` as two separate operations. Concurrent requests can all observe available quota before any request increments it. The built-in memory store also reads and writes its map without synchronization.
The proxy ignores the boolean returned by `TallyFreebie`, so a custom implementation returning `false, nil` does not prevent the request from being forwarded.
## Impact
- Concurrent clients can exceed the configured freebie quota.
- The memory store has data races and can fail with concurrent map access.
- A rejected tally result from a custom store can be treated as successful admission.
A local race repro with a quota of one allowed all 32 concurrent callers past the eligibility check.
## Proposed direction
Replace the split check/tally protocol with one authoritative atomic operation, for example:
```go
TryConsumeFreebie(*http.Request, net.IP) (bool, error)
```
The memory implementation should check and increment under a mutex. Persistent implementations should use their native transaction/conditional-update mechanism. Freebie correctness should not depend on a rate-limiter lock.
## Acceptance criteria
- With quota 1, exactly one of many concurrent callers is admitted.
- The memory implementation passes the race detector.
- A false consumption result is never forwarded.
- Counters do not wrap back into an eligible state.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the freebie admission path that calls DB.CanPass and DB.TallyFreebie, then inspect the memory store and persistent implementations. Run the concurrent quota-one reproduction under the race detector. Done means one caller is admitted, the memory implementation is race-free, false consumption results are rejected, and counters cannot wrap into eligibility.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, backend, databases, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100