Skip to content

feat: wire up Execution DAG engine and in-browser event search worker - #414

Merged
Osuochasam merged 3 commits into
Open-audit-foundation:mainfrom
ScriptedBro:feat/dag-engine-and-event-search
Aug 25, 2026
Merged

feat: wire up Execution DAG engine and in-browser event search worker#414
Osuochasam merged 3 commits into
Open-audit-foundation:mainfrom
ScriptedBro:feat/dag-engine-and-event-search

Conversation

@ScriptedBro

@ScriptedBro ScriptedBro commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Wire two fully-built but completely disconnected subsystems into the application so they actually run, persist data, and are visible in the UI.

Closes #408


Execution DAG Engine (lib/dag/)

The lib/dag/engine.ts module could reconstruct Soroban cross-contract call trees from TransactionMeta XDR, but nothing in the codebase ever called it. Now it does.

  • Reentrancy detection: Stack-based DFS algorithm that detects when a contract address appears more than once along a single root-to-leaf execution path (the textbook reentrancy pattern). Returns full call paths and affected contracts, not just a boolean. Correctly handles sequential repeated calls (not reentrant) without false positives.
  • Auth tracing: extractTopLevelAccounts correlates Stellar authorization entries from transaction metadata with DAG nodes to answer "whose authorization made this specific nested call possible." The indexer passes tx.source_account as the top-level authorizing account for each reconstructed DAG.
  • Persistence: New ExecutionDag Prisma model stores reconstructed DAGs linked to events, queryable after the fact. Includes a Prisma migration.
  • Indexer wiring: onDag callback in server.ts and src/worker/indexer.ts produces and persists DAGs for every Soroban transaction that has diagnostic events.
  • API: GET /api/v1/dag with query params for txHash, id, ledger, and reentrancy (boolean flag filter). Returns the full DAG including reentrancyDetails, authTraces, and per-node authorizedBy fields.
  • Visualization: Interactive DagPanel component with collapsible tree nodes, contract address badges, kind labels (contract_fn/create_contract/system_fn), reentrancy path highlighting, and an auth trace info panel. Replaced the placeholder /dag page with a real transaction search interface.

In-Browser Event Search Worker (lib/workers/)

The lib/workers/eventSearch.worker.ts and lib/workers/eventSearchClient.ts implemented a full inverted-index search engine over event text fields, but nothing in the dashboard ever called it. Now it runs.

  • Incremental indexing: Added ADD_EVENTS/REMOVE_EVENTS message types to the worker so the index updates as new events stream in without a full rebuild.
  • Client wrapper: Added addEvents(), removeEvents(), and destroy() methods to EventSearchClient.
  • React hook: New useEventSearch hook with 300ms debounced search, lazy worker instantiation, and proper cleanup on unmount. Falls back to synchronous main-thread search when Web Workers are unavailable.
  • Dashboard integration: Full-text search input in the event feed that queries the Web Worker in a background thread, alongside the existing server-side contract ID search. Shows a fallback indicator when running on the main thread.

Prisma

  • New ExecutionDag model with fields for txHash, ledger, contractId, reentrancy, reentrancyDetails (JSON), authTraces (JSON), dagData (JSON), and timestamps.
  • New executionDagId foreign key on the Event model.
  • Migration: 20260825000000_add_execution_dag_model.

Tests (47 passing)

  • 19 DAG engine tests (lib/dag/engine.test.ts):
    • 4 reentrancy positive cases (direct A→B→A, chain A→B→C→A, self-reentrancy, multi-branch)
    • 7 reentrancy negative cases (sequential calls, deep trees, separate branches, system functions, single node, A→B + A→C)
    • 3 edge cases (empty, single root, disconnected roots)
    • 3 auth tracing tests (explicit auth attribution, no-auth nodes, multiple authorized nodes)
  • 8 event search hook tests (lib/workers/eventSearchClient.test.ts): Worker lifecycle cleanup, debounce, index building, incremental add, search results, clear results, empty query, isFallback check.
  • 10 EventSearchClient unit tests (lib/workers/eventSearchClient.unit.test.ts): API contract, buildIndex, addEvents, removeEvents, search, destroy, hash skip/rebuild, SEARCH_ERROR handling.
  • 9 API route tests (app/api/v1/dag/route.test.ts): txHash/id/ledger queries, reentrancy filter, 400/404/500 error handling, invalid ledger rejection.

ScriptedBro and others added 3 commits August 25, 2026 10:14
Wire the fully-built but disconnected DAG reconstruction engine into the
application pipeline so Soroban cross-contract call trees are actually
produced, persisted, analyzed, and visible in the UI.

Wire the in-browser inverted-index event search worker into the dashboard
so the live event feed has instant client-side full-text search.

Execution DAG (Issue Open-audit-foundation#8):
- Enhance DagNode types with authorizedBy, reentrancyDetails, authTraces
- Implement stack-based reentrancy detection with full call path tracking
- Implement auth tracing to attribute Stellar accounts to DAG nodes
- Add ExecutionDag Prisma model with migration support
- Wire onDag callback in server.ts and worker/indexer.ts for persistence
- Create GET /api/v1/dag API route with txHash, id, ledger, reentrancy queries
- Build interactive DagPanel visualization with collapsible nodes, reentrancy
  highlighting, auth badges, and contract filtering
- Replace placeholder DAG page with real transaction search and visualization

Event Search Worker (Issue Open-audit-foundation#9):
- Add ADD_EVENTS/REMOVE_EVENTS message types to event search worker
- Add addEvents/removeEvents/destroy to EventSearchClient wrapper
- Create useEventSearch hook with debounced search and incremental indexing
- Wire client-side full-text search into DashboardClient alongside server search
- Worker properly cleaned up on component unmount

Tests:
- 16 reentrancy detection tests: positive (direct, chain, self, multi-branch),
  negative (sequential, deep linear, separate branches, system fn, empty),
  and edge cases
- 7 event search hook tests: worker lifecycle, debounce, index building,
  incremental updates, search results, clear results

Closes Open-audit-foundation#408
…tests, fallback

Fix 5 gaps identified by acceptance criteria audit:

Auth tracing:
- Implement extractTopLevelAccounts (was a stub returning [])
- Accept optional authAddresses param in reconstructDagFromMetaXdr
- Pass tx.source_account from indexer as top-level authorizing account
- Add 3 auth tracing tests: explicit auth attribution, no-auth nodes,
  multiple authorized nodes in a tree

Prisma migration:
- Create migration SQL for ExecutionDag table + Event.executionDagId FK

API route tests:
- 9 tests for GET /api/v1/dag: txHash, id, ledger, reentrancy queries,
  400 for missing params, 404 for not found, invalid ledger, error handling

Web Worker fallback:
- Implement synchronous main-thread search in useEventSearch hook
- Track isFallback state, display fallback indicator in dashboard
- Fallback handles buildIndex, addEvents, removeEvents, and search

EventSearchClient unit tests:
- 10 tests covering buildIndex, addEvents, removeEvents, search,
  destroy lifecycle, hash-based skip/rebuild, SEARCH_ERROR handling

Also fix: persistence.ts import paths (./client -> ../db/client, ../dag/types -> ./types)
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.

Wire up the Execution DAG engine — reentrancy detection, auth tracing, and dashboard visualization

2 participants