fix(exchange): enforce daily-cap integrity on manual path, actual-paid ledger, and headroom (adversarial-review follow-ups)#1457
Conversation
|
@coderabbitai review |
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 48 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (13)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
✅ Action performedReview finished.
|
…d ledger, and headroom (adversarial-review follow-ups)
H1: checkDailyCap fails closed on unparseable paymentDue (was treating as $0).
H2: executeApprovedExchange and processAutoExchange bound Execute MaxPaymentDueUSD
by min(perExchangeCap, dailyCap-dailySpent) so re-quotes cannot breach headroom.
H3: Add CompleteRIExchangeWithPayment to persist the accepted (not pre-execution)
amount; both auto and manual paths use the fresh quote from Execute.
H4: Retry ledger write 3x after money moves; halt auto run / return 500 on
persistent failure to prevent cap bypass via missing ledger rows.
M5: GetRIExchangeDailySpend includes processing rows (COALESCE on completed_at/
updated_at) to close concurrent-approval TOCTOU window.
Each defect has a regression test that fails pre-fix and passes post-fix.
…uteHeadroom Fixes golangci-lint errcheck failure on handler_ri_exchange.go:1351 where `exchange.ParseDecimalRat` error was discarded with `_`. The fix extracts a `checkCapsAndComputeHeadroom` helper that bundles the three cap-validation checks (MaxDailyUSD==0, checkDailyCap, MaxPerExchangeUSD==0) and the headroom calculation, properly returning a reason string on any parse failure (fail closed). This also brings `executeApprovedExchange` back under gocyclo -over 10 (complexity 8) after the helper reduces it from the 12 that errcheck enforcement would have caused. Rebased onto main (after PR #1456 merged; no conflicts in store_postgres.go).
d78f295 to
62e4823
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
Summary
Five verified money-integrity defects in the RI Exchange daily-cap subsystem, fixed with regression tests.
checkDailyCapinhandler_ri_exchange.gowas treating an unparseablepaymentDueas $0 and proceeding. Now fails closed with a blocking reason (mirrors the existingdailySpentparse-failure path).executeApprovedExchangeandprocessAutoExchangepassed the fullperExchangeCapasMaxPaymentDueUSDtoExecute. A fresh re-quote could accept an amount that exceeds remaining daily headroom. Fixed:effectiveCap = min(perExchangeCap, dailyCap - dailySpent).Executewas discarded (_, _). Completed records persisted the stale pre-execution quote.GetRIExchangeDailySpendsums ledger amounts, so the daily spend was systematically under-counted. Fixed: newCompleteRIExchangeWithPaymentmethod persists the accepted amount; both paths use it.CompleteRIExchange/SaveRIExchangeRecordwrites after money moved were log-and-continue. The daily ledger would under-count, allowing subsequent exchanges to bypass the cap. Fixed: 3-attempt retry; auto run halts / handler returns HTTP 500 on persistent failure.GetRIExchangeDailySpendonly summedstatus = 'completed'rows. Concurrent approvals both read the same spend total before either write commits (TOCTOU). Fixed: SQL now includes'processing'rows viaCOALESCE(completed_at, updated_at)date filter.Test plan
TestCheckDailyCap_UnparseablePaymentDue_FailsClosed,TestProcessAutoExchange_EffectiveCap_BoundedByDailyHeadroom,TestProcessAutoExchange_AcceptedAmountFromFreshQuote,TestProcessAutoExchange_LedgerSaveFailure_HaltsAndReturnsError,TestRunAutoExchange_LedgerSaveFailure_StopsAfterFirstExchange,TestExecuteApprovedExchange_EffectiveCap_BoundedByDailyHeadroom,TestExecuteApprovedExchange_AcceptedAmountFromFreshQuote,TestExecuteApprovedExchange_LedgerWriteFailure_ReturnsError)