Skip to content

Cap abci loop#236

Merged
nullpointer0x00 merged 3 commits into
mainfrom
nullpointer0x00/225-cap-abci-loop
Jul 15, 2026
Merged

Cap abci loop#236
nullpointer0x00 merged 3 commits into
mainfrom
nullpointer0x00/225-cap-abci-loop

Conversation

@nullpointer0x00

@nullpointer0x00 nullpointer0x00 commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

closes: #225

Summary by CodeRabbit

  • New Features
    • Added per-block visit/batch budgets for interest timeouts, AUM fee timeouts, payout verifications, and due swap-out processing.
  • Bug Fixes
    • Paused-vault swap-out requests are now dequeued and refunded when due, preventing them from stalling or skipping order; swap-out refund events now include a dedicated vault_paused reason.
    • Updated pending/paused handling to ensure remaining due work is left for later blocks.
  • Documentation
    • Refreshed swap-out/expedite guidance to reflect the new “dequeued and refunded when due” paused behavior.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c37115a3-0f76-488b-bb88-6c1c242691c2

📥 Commits

Reviewing files that changed from the base of the PR and between c49448e and 0fd2aec.

📒 Files selected for processing (7)
  • keeper/abci.go
  • keeper/payout.go
  • keeper/payout_test.go
  • keeper/reconcile.go
  • keeper/reconcile_test.go
  • keeper/suite_test.go
  • spec/06_blocker.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • keeper/abci.go
  • keeper/suite_test.go
  • keeper/reconcile_test.go
  • keeper/reconcile.go
  • spec/06_blocker.md
  • keeper/payout_test.go

📝 Walkthrough

Walkthrough

This PR enforces per-block visit budgets across ABCI queue processors and pending swap-out processing. Paused-vault swap-outs are now dequeued and refunded with a new refund reason. Tests, specifications, and the changelog document the updated behavior.

Changes

Per-block budgets and paused-vault swap-out refunds

Layer / File(s) Summary
Refund reason and reconciliation budgets
types/events.go, keeper/abci.go, keeper/reconcile.go, keeper/export_test.go
Adds RefundReasonVaultPaused; limits interest timeout, fee timeout, and payout verification processing; wires limits through ABCI handlers and test accessors.
Paused-vault swap-out handling
keeper/payout.go
Counts all visited entries toward the batch budget and dequeues/refunds paused-vault jobs using a cache context.
Budget and refund coverage
keeper/reconcile_test.go, keeper/payout_test.go, keeper/suite_test.go
Adds queue-counting helpers and tests for backlog draining, paused-entry budget consumption, refunds, failures, and queue state.
Specifications and changelog
spec/*.md, .changelog/unreleased/bug-fixes/225-cap-abci-loop.md
Documents per-block budgets, paused-vault refunds, expedited requests, and event behavior.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant BeginBlocker
  participant EndBlocker
  participant ReconcileHandlers
  participant processPendingSwapOuts
  participant processSwapOutJobs
  participant refundPausedVaultSwapOut

  BeginBlocker->>ReconcileHandlers: process bounded timeout queues
  EndBlocker->>ReconcileHandlers: process bounded verification set
  EndBlocker->>processPendingSwapOuts: process MaxSwapOutBatchSize visited entries
  processPendingSwapOuts->>processSwapOutJobs: pass collected jobs
  processSwapOutJobs->>refundPausedVaultSwapOut: refund paused-vault job
  refundPausedVaultSwapOut-->>processSwapOutJobs: dequeue and emit vault_paused refund event
Loading

Possibly related PRs

Suggested labels: bug

Suggested reviewers: taztingo

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and directly reflects the main change: capping the ABCI loop.
Linked Issues check ✅ Passed The PR implements the requested per-block budgets, visited-entry counting, paused swap-out handling, and supporting tests for #225.
Out of Scope Changes check ✅ Passed The changes stay focused on ABCI queue budgeting, paused swap-outs, tests, and related docs without obvious unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch nullpointer0x00/225-cap-abci-loop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR enforces per-block visit budgets on all four ABCI queue processors (interest timeouts, fee timeouts, payout verification set, and pending swap-outs) and changes the paused-vault swap-out strategy from "leave queued indefinitely" to "atomically dequeue and refund," preventing stale entries from camping at the queue front and starving processable requests.

  • Budget enforcement (keeper/abci.go, keeper/reconcile.go): Three new constants (MaxInterestTimeoutsPerBlock, MaxFeeTimeoutsPerBlock, MaxPayoutVerificationsPerBlock, all 100) are added and threaded through handleVaultInterestTimeouts, handleVaultFeeTimeouts, and handleReconciledVaults. Paused-vault entries count against the budget but stay enqueued (intentional — unpause re-scheduling depends on them).
  • Paused-vault swap-out refund (keeper/payout.go): processPendingSwapOuts now collects every due entry (including paused-vault entries) against the budget. processSwapOutJobs calls the new refundPausedVaultSwapOut, which dequeues and returns escrowed shares in a single cache context, committing only when both succeed; on failure the cache is discarded and the request stays queued to retry later.
  • Test coverage (keeper/payout_test.go, keeper/reconcile_test.go): New table-driven tests verify zero/under/over-budget draining for all four processors, the happy-path paused-vault refund, the refund-failure path (request stays queued, no events emitted), and the documented starvation boundary for timeout queues.

Confidence Score: 5/5

Safe to merge; the logic is correct, the atomic cache-context pattern for paused-vault refunds is sound, and every new code path is covered by dedicated tests.

All four queue processors now correctly enforce per-block visit budgets. The paused-vault swap-out refund uses a single cache context so that dequeue and share-return either both commit or both roll back, eliminating the stuck-funds risk flagged in an earlier review round. The acknowledged starvation asymmetry for timeout/verification queues is intentional, documented, and boundary-tested. No correctness issues were found in the diff.

No files require special attention.

Important Files Changed

Filename Overview
keeper/abci.go Adds three budget constants and threads them as arguments to the four queue processors; straightforward and correct.
keeper/payout.go Removes the inline paused-vault skip in the collection walk; adds refundPausedVaultSwapOut with correct single-cache-context atomicity (dequeue + refund commit together or not at all).
keeper/reconcile.go Adds per-block visit budgets to handleVaultInterestTimeouts, handleVaultFeeTimeouts, and handleReconciledVaults; paused entries consume budget slots but remain enqueued (intentional per design).
keeper/payout_test.go Adds comprehensive tests: happy-path paused-vault dequeue+refund, refund-failure path, and batch-budget starvation scenario; all match the implemented behavior.
keeper/reconcile_test.go Adds per-block visit-budget tests for all three reconcile processors (zero/under/over-budget) and the paused-front starvation boundary; correctly documents the accepted asymmetry.
types/events.go Adds RefundReasonVaultPaused constant; consistent with the existing refund-reason pattern.
keeper/suite_test.go Adds four queue-counting helpers used across new tests.
keeper/export_test.go Updates three test accessors to forward the new limit parameter; mechanical change, no issues.
spec/06_blocker.md Documentation accurately reflects the new per-block budget semantics and paused-vault refund behavior for all processors.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant EB as EndBlocker
    participant PSO as processPendingSwapOuts
    participant PSJ as processSwapOutJobs
    participant RPV as refundPausedVaultSwapOut
    participant Q as PendingSwapOutQueue
    participant Bank as BankKeeper

    EB->>PSO: "processPendingSwapOuts(ctx, batchSize=100)"
    PSO->>Q: WalkDue(now)
    note over PSO,Q: All entries count against budget (paused or not)
    PSO->>PSJ: processSwapOutJobs(ctx, jobsToProcess)

    alt vault not found
        PSJ->>Q: Dequeue and skip
    else vault.Paused
        PSJ->>RPV: refundPausedVaultSwapOut(ctx, job)
        RPV->>RPV: "cacheCtx, write = ctx.CacheContext()"
        RPV->>Q: Dequeue(cacheCtx)
        alt Dequeue fails
            RPV-->>PSJ: log error, entry stays queued
        else Dequeue succeeds
            RPV->>Bank: refundWithdrawal(cacheCtx, vault_paused)
            alt refund fails
                RPV-->>PSJ: log error, cache discarded, entry stays queued
            else refund succeeds
                RPV->>RPV: write() commit atomically
                note over RPV: EventSwapOutRefunded emitted
            end
        end
    else vault active
        PSJ->>PSJ: processSingleWithdrawal normal path
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant EB as EndBlocker
    participant PSO as processPendingSwapOuts
    participant PSJ as processSwapOutJobs
    participant RPV as refundPausedVaultSwapOut
    participant Q as PendingSwapOutQueue
    participant Bank as BankKeeper

    EB->>PSO: "processPendingSwapOuts(ctx, batchSize=100)"
    PSO->>Q: WalkDue(now)
    note over PSO,Q: All entries count against budget (paused or not)
    PSO->>PSJ: processSwapOutJobs(ctx, jobsToProcess)

    alt vault not found
        PSJ->>Q: Dequeue and skip
    else vault.Paused
        PSJ->>RPV: refundPausedVaultSwapOut(ctx, job)
        RPV->>RPV: "cacheCtx, write = ctx.CacheContext()"
        RPV->>Q: Dequeue(cacheCtx)
        alt Dequeue fails
            RPV-->>PSJ: log error, entry stays queued
        else Dequeue succeeds
            RPV->>Bank: refundWithdrawal(cacheCtx, vault_paused)
            alt refund fails
                RPV-->>PSJ: log error, cache discarded, entry stays queued
            else refund succeeds
                RPV->>RPV: write() commit atomically
                note over RPV: EventSwapOutRefunded emitted
            end
        end
    else vault active
        PSJ->>PSJ: processSingleWithdrawal normal path
    end
Loading

Reviews (3): Last reviewed commit: "fix conflicts" | Re-trigger Greptile

Comment thread keeper/reconcile.go
Comment thread keeper/payout.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
keeper/payout_test.go (1)

356-398: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Setup block duplicates existing swap-in/escrow boilerplate.

This new case repeats the same CreateAndFundAccount/setupBaseVault/SwapIn/escrow/enqueue sequence already present in several sibling table entries in this test. As per path instructions, **/*_test.go: "If a setup block (marker creation, vault setup, funding) appears in three or more tests, it MUST be extracted into a helper in suite_test.go." This pattern already recurs well beyond 3 times in this table; consider extracting a shared setupPendingSwapOut(shareDenom, assets) helper as a follow-up cleanup (not necessarily scoped to this PR).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@keeper/payout_test.go` around lines 356 - 398, The setup block in this
table-driven case duplicates the same swap-in, escrow, and enqueue boilerplate
used by several sibling tests. Refactor the repeated logic in this
`payout_test.go` case by extracting the shared account funding,
`setupBaseVault`, `SwapIn`, escrow, and `PendingSwapOutQueue.Enqueue` flow into
a helper in `suite_test.go` (for example, a shared pending-swap-out setup
helper). Keep the test case focused on the paused-vault behavior and reuse the
helper from this case and the other matching table entries.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@keeper/payout_test.go`:
- Around line 356-398: The setup block in this table-driven case duplicates the
same swap-in, escrow, and enqueue boilerplate used by several sibling tests.
Refactor the repeated logic in this `payout_test.go` case by extracting the
shared account funding, `setupBaseVault`, `SwapIn`, escrow, and
`PendingSwapOutQueue.Enqueue` flow into a helper in `suite_test.go` (for
example, a shared pending-swap-out setup helper). Keep the test case focused on
the paused-vault behavior and reuse the helper from this case and the other
matching table entries.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 21583ec3-e8f4-4b46-975d-754498fc1102

📥 Commits

Reviewing files that changed from the base of the PR and between 21d45e2 and c49448e.

📒 Files selected for processing (12)
  • .changelog/unreleased/bug-fixes/225-cap-abci-loop.md
  • keeper/abci.go
  • keeper/export_test.go
  • keeper/payout.go
  • keeper/payout_test.go
  • keeper/reconcile.go
  • keeper/reconcile_test.go
  • keeper/suite_test.go
  • spec/03_messages.md
  • spec/04_events.md
  • spec/06_blocker.md
  • types/events.go

@nullpointer0x00 nullpointer0x00 self-assigned this Jul 2, 2026
@nullpointer0x00 nullpointer0x00 requested a review from Taztingo July 2, 2026 19:32
@Taztingo Taztingo added the ready This PR is ready to be reviewed. label Jul 13, 2026

@Taztingo Taztingo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM. Great improvement.

@nullpointer0x00 nullpointer0x00 merged commit 90a3425 into main Jul 15, 2026
16 checks passed
@nullpointer0x00 nullpointer0x00 deleted the nullpointer0x00/225-cap-abci-loop branch July 15, 2026 18:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready This PR is ready to be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enforce per-block work budgets across all ABCI queue processors

2 participants