Skip to content

Conversation

@eabdelmoneim
Copy link
Contributor

@eabdelmoneim eabdelmoneim commented Feb 2, 2026

Changes

How this PR will be tested

  • Open the dashboard and click X. Result: A modal should appear.
  • Call the /foo/bar API. Result: Returns 200 with "baz" in the response body.

Output

(Example: Screenshot/GIF for UI changes, cURL output for API changes)


PR-Codex overview

This PR introduces functionality for managing transaction backfills in the application. It adds routes for loading and clearing backfill entries, updates the environment configuration to enable backfill fallback, and enhances the transaction status retrieval logic with backfill support.

Detailed summary

  • Added loadBackfillRoute and clearBackfillRoute in src/server/routes/admin/backfill.ts.
  • Updated withRoutes in src/server/routes/index.ts to register new routes.
  • Introduced ENABLE_TX_BACKFILL_FALLBACK in src/shared/utils/env.ts.
  • Enhanced getTransactionLogs and transaction status routes to utilize backfill data.
  • Implemented getBackfill, getBackfillHash, setBackfill, and bulkSetBackfill methods in TransactionDB for managing backfill entries.
  • Added BackfillEntry interface to define backfill data structure in src/shared/db/transactions/db.ts.
  • Created logic for generating responses from backfill data in getTransactionStatusRoute.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • New Features

    • Fallback mechanism to recover missing transaction hashes from a backfill store when primary lookups fail, returning consistent transaction status responses.
    • Admin endpoints to bulk upload backfill entries and to clear backfill records, with reporting of inserted/skipped or deleted counts.
  • Chores

    • Added ENABLE_TX_BACKFILL_FALLBACK environment flag (default: disabled) to toggle the backfill fallback behavior.

eabdelmoneim and others added 6 commits January 30, 2026 11:06
- Add ENABLE_TX_BACKFILL_FALLBACK env var (default: false)
- Add backfill methods to TransactionDB (getBackfillHash, setBackfill, bulkSetBackfill)
- Add fallback lookup in /transaction/logs endpoint
- Add POST /admin/backfill endpoint for loading backfill data

When enabled, the /transaction/logs endpoint will check a fallback
Redis table (backfill:<queueId>) when the primary transaction cache
misses. This allows recovering transaction logs for queue IDs that
were pruned from the main cache.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add isHex validation to prevent unexpected behavior if malformed
data exists in the backfill table.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add BackfillEntry interface with status field ("mined" | "errored")
- Update TransactionDB to store/retrieve JSON format for backfill entries
- Add backfill fallback lookup to /transaction/status routes
- Update /transaction/logs to use new getBackfill method
- Update admin backfill schema to accept status field
- Maintain backwards compatibility for plain string tx hash entries

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Feb 2, 2026

Walkthrough

Adds Redis-backed backfill storage and admin routes to bulk-load/clear backfilled transaction hashes, plus fallback lookup logic in transaction status/log endpoints controlled by ENABLE_TX_BACKFILL_FALLBACK.

Changes

Cohort / File(s) Summary
Admin Backfill Routes
src/server/routes/admin/backfill.ts, src/server/routes/index.ts
New admin endpoints: POST /admin/backfill to bulk-insert backfill entries and DELETE /admin/backfill to clear entries. Use TypeBox schemas, standard response handling, and hidden-from-docs registration.
Database Backfill Operations
src/shared/db/transactions/db.ts
Adds BackfillEntry type, backfillKey helper, and TransactionDB methods: getBackfill, getBackfillHash (deprecated helper), setBackfill (SETNX), bulkSetBackfill (pipeline with SETNX), and clearBackfill (scan+UNLINK). Handles legacy plain-string values and returns insert/skip counts or deleted count.
Transaction Lookup Fallback
src/server/routes/transaction/status.ts, src/server/routes/transaction/blockchain/get-logs.ts
Adds conditional fallback to query backfill via TransactionDB.getBackfill(queueId) when primary transaction/hash lookup fails. Introduces createBackfillResponse helper and uses env.ENABLE_TX_BACKFILL_FALLBACK to gate behavior.
Environment Configuration
src/shared/utils/env.ts
Adds ENABLE_TX_BACKFILL_FALLBACK boolean env var (default false) to runtime strict env schema.

Sequence Diagram(s)

sequenceDiagram
    actor Admin
    participant Route as Admin Route<br/>/admin/backfill
    participant DB as TransactionDB
    participant Redis as Redis
    Admin->>Route: POST /admin/backfill (entries: queueId,status,txHash?)
    Route->>DB: bulkSetBackfill(entries)
    DB->>Redis: SETNX backfill:queueId (per entry, pipelined)
    Redis-->>DB: inserted/skipped results
    DB-->>Route: {inserted, skipped}
    Route-->>Admin: 200 OK
Loading
sequenceDiagram
    actor Client
    participant Route as Transaction Route<br/>(status/logs)
    participant Cache as Redis Cache
    participant DB as TransactionDB
    participant Backfill as Redis Backfill
    Client->>Route: GET /transaction/{queueId}
    Route->>Cache: lookup transaction
    Cache-->>Route: null
    alt ENABLE_TX_BACKFILL_FALLBACK enabled
        Route->>DB: getBackfill(queueId)
        DB->>Backfill: GET backfill:queueId
        Backfill-->>DB: BackfillEntry (or legacy string)
        DB-->>Route: {status, transactionHash?}
        Route->>Route: createBackfillResponse()
        Route-->>Client: 200 OK (backfilled response)
    else fallback disabled or no backfill
        Route-->>Client: 400 TRANSACTION_NOT_FOUND
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Feature/tx backfill fallback' clearly and concisely summarizes the main change: adding a transaction backfill fallback mechanism.
Description check ✅ Passed The description includes the required sections: a Linear issue link (PRO-183), a detailed PR-Codex summary explaining the changes, and testing steps.
Linked Issues check ✅ Passed All coding requirements from PRO-183 are met: admin backfill routes created, GET /transaction/logs and GET /transaction/status enhanced with backfill fallback, and TransactionDB methods implemented.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing the backfill fallback feature as specified in PRO-183; no out-of-scope modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/tx-backfill-fallback

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/server/routes/admin/backfill.ts`:
- Around line 19-35: The schema allows entries with status "mined" to omit
transactionHash — update loadRequestBodySchema to enforce transactionHash when
status === "mined" by replacing the current entry object with a discriminated
union: one variant for { status: "mined", queueId: string, transactionHash:
string } and another for { status: "errored", queueId: string, transactionHash?:
string } (or omit transactionHash), using the status field as the discriminator
for entries so validation fails if a mined entry lacks transactionHash.
- Around line 7-17: The top-of-file comment for the AMEX special logic is
duplicated; remove the repeated block so there is a single explanatory comment
describing the two admin routes (loadBackfillRoute and clearBackfillRoute) and
the link to the AMEX script. Edit the comment near the definitions of
loadBackfillRoute and clearBackfillRoute to keep only one copy of the
explanatory lines (mentioning the purpose and the GitHub link) and delete the
redundant duplicate immediately following it.
🧹 Nitpick comments (4)
src/shared/db/transactions/db.ts (1)

281-288: Error handling conflates Redis errors with "key exists" results.

When err is truthy, the code increments skipped, but this masks actual Redis errors. A SETNX returning 0 (key exists) is different from a Redis error. Consider logging or surfacing errors distinctly.

🔧 Proposed fix to distinguish errors from skipped entries
     const results = await pipeline.exec();
+    let errors = 0;
     for (const [err, result] of results ?? []) {
-      if (!err && result === 1) {
+      if (err) {
+        errors++;
+      } else if (result === 1) {
         inserted++;
       } else {
         skipped++;
       }
     }
 
-    return { inserted, skipped };
+    return { inserted, skipped, errors };
src/server/routes/transaction/status.ts (2)

17-82: Consider handling errored backfills and potential on-chain failures.

The createBackfillResponse assumes all "mined" transactions were successful on-chain (onchainStatus: "success"). However:

  1. A mined transaction could have reverted on-chain (status would be "mined" but onchainStatus should be "failed")
  2. For "errored" backfills, the response returns status: "errored" but no additional context

Consider extending BackfillEntry to capture revert status, or document the assumption that backfilled transactions are known to be successful.

💡 Optional enhancement for errored state clarity
   if (backfill.status === "mined" && backfill.transactionHash) {
     return {
       ...baseResponse,
       transactionHash: backfill.transactionHash,
       onchainStatus: "success",
       onChainTxStatus: 1,
     };
   }
 
+  if (backfill.status === "errored") {
+    return {
+      ...baseResponse,
+      errorMessage: "Transaction failed (backfill data)",
+    };
+  }
+
   return baseResponse;

150-162: Duplicated fallback logic across both route handlers.

The backfill fallback logic is copy-pasted in both getTransactionStatusRoute and getTransactionStatusQueryParamRoute. Consider extracting to a shared helper to reduce duplication and ensure consistent behavior.

♻️ Proposed refactor to extract shared logic
// Add helper function
async function getTransactionOrBackfill(
  queueId: string,
): Promise<{ transaction: AnyTransaction } | { backfill: BackfillEntry } | null> {
  const transaction = await TransactionDB.get(queueId);
  if (transaction) {
    return { transaction };
  }
  
  if (env.ENABLE_TX_BACKFILL_FALLBACK) {
    const backfill = await TransactionDB.getBackfill(queueId);
    if (backfill) {
      return { backfill };
    }
  }
  
  return null;
}

Then use in both handlers to eliminate duplication.

Also applies to: 211-223

src/server/routes/admin/backfill.ts (1)

26-28: Missing hex format validation for transactionHash.

The transactionHash field accepts any string, but transaction hashes should be valid hex (0x-prefixed, 66 characters). The get-logs.ts route validates with isHex() at read time, but rejecting invalid hashes at write time provides better feedback.

🔒 Add pattern validation to schema
       transactionHash: Type.Optional(
-        Type.String({ description: "Transaction hash (0x...). Required for mined transactions." }),
+        Type.String({
+          description: "Transaction hash (0x...). Required for mined transactions.",
+          pattern: "^0x[a-fA-F0-9]{64}$",
+        }),
       ),

… comment

- Use discriminated union so transactionHash is required for mined entries
- Remove duplicated AMEX comment block

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@nischitpra nischitpra merged commit ec98297 into main Feb 2, 2026
8 checks passed
@nischitpra nischitpra deleted the feature/tx-backfill-fallback branch February 2, 2026 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants