@secondlayer/subgraphs 3.26.4 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -366,21 +366,10 @@ type EventRecord = {
366
366
  };
367
367
  import { Database as Database2 } from "@secondlayer/shared/db";
368
368
  import { Kysely as Kysely2, Transaction } from "kysely";
369
- /** f072: thrown by `resolveRoute` when a BYO subgraph needs its user-DB
370
- * connection decrypted but this process holds no `SECONDLAYER_SECRETS_KEY`
371
- * — the subgraph processor deliberately does not hold the master key (it
372
- * runs untrusted handler code in-process, every block; see f049 site 3 /
373
- * the sandbox spike doc's D3). Deny by default, fail loud: this must NEVER
374
- * be caught and silently rerouted to the managed target DB, since that
375
- * would write a tenant's rows into ours — far worse than halting the
376
- * block. */
377
- declare class ByoKeyUnavailableError extends Error {
378
- constructor(subgraphName: string);
379
- }
380
369
  /** Drop a subgraph's cached route — call on redeploy/delete (conn may
381
370
  * change). Also evicts any warm sandbox subprocess for this subgraph
382
371
  * (f071 Stage A `host.ts`) on the same edge: a redeploy can change
383
- * `handler_code`/`version`/the BYO connection together, and a stale warm
372
+ * `handler_code`/`version` together, and a stale warm
384
373
  * subprocess must not survive past this invalidation any more than the
385
374
  * cached route does. A no-op today since nothing sets `sandbox_workers`,
386
375
  * but keeps the pool's documented invalidation contract honest for when it
@@ -491,4 +480,4 @@ declare const BLOCK_RETRY_DELAYS_MS: number[];
491
480
  */
492
481
  declare function processBlockWithRetry(subgraph: SubgraphDefinition, subgraphName: string, blockHeight: number, opts?: ProcessBlockOptions, retryDelaysMs?: number[]): Promise<ProcessBlockResult>;
493
482
  declare function processBlock(subgraph: SubgraphDefinition, subgraphName: string, blockHeight: number, opts?: ProcessBlockOptions): Promise<ProcessBlockResult>;
494
- export { resolveFactoryContracts, processBlockWithRetry, processBlock, invalidateSubgraphRoute, ProcessBlockTiming, ProcessBlockResult, ProcessBlockOptions, PreloadedBlockData, ByoKeyUnavailableError, BLOCK_RETRY_DELAYS_MS };
483
+ export { resolveFactoryContracts, processBlockWithRetry, processBlock, invalidateSubgraphRoute, ProcessBlockTiming, ProcessBlockResult, ProcessBlockOptions, PreloadedBlockData, BLOCK_RETRY_DELAYS_MS };
@@ -323,16 +323,14 @@ class SubgraphContext {
323
323
  pgSchemaName;
324
324
  subgraphSchema;
325
325
  ops = [];
326
- byo;
327
326
  journal;
328
327
  _client;
329
- constructor(db, pgSchemaName2, subgraphSchema, block, tx, byo = false, journal = false) {
328
+ constructor(db, pgSchemaName2, subgraphSchema, block, tx, journal = false) {
330
329
  this.db = db;
331
330
  this.pgSchemaName = pgSchemaName2;
332
331
  this.subgraphSchema = subgraphSchema;
333
332
  this.block = block;
334
333
  this._tx = tx;
335
- this.byo = byo;
336
334
  this.journal = journal;
337
335
  }
338
336
  get client() {
@@ -701,15 +699,6 @@ class SubgraphContext {
701
699
  }
702
700
  buildStatements(ops) {
703
701
  const statements = [];
704
- if (this.byo) {
705
- const insertTables = new Set;
706
- for (const op of ops)
707
- if (op.kind === "insert")
708
- insertTables.add(op.table);
709
- for (const table of insertTables) {
710
- statements.push(`DELETE FROM "${this.pgSchemaName}"."${table}" WHERE "_block_height" = ${this.block.height}`);
711
- }
712
- }
713
702
  let currentBatch = null;
714
703
  let currentBatchKey = "";
715
704
  let incBatch = null;
@@ -1662,16 +1651,13 @@ function matchSources(sources, transactions, events, traitContracts = new Map, f
1662
1651
  }
1663
1652
 
1664
1653
  // src/runtime/block-processor.ts
1665
- import { secretsKeyAvailable } from "@secondlayer/shared/crypto/secrets";
1666
1654
  import { getTargetDb } from "@secondlayer/shared/db";
1667
1655
  import { resolveTraitContractIds } from "@secondlayer/shared/db/queries/contracts";
1668
1656
  import { advanceOperationCursor } from "@secondlayer/shared/db/queries/subgraph-operations";
1669
1657
  import {
1670
- isByoSubgraph,
1671
1658
  recordLiveError,
1672
1659
  recordLiveProgress,
1673
1660
  recordSubgraphProcessed,
1674
- resolveSubgraphDb,
1675
1661
  rewindLiveProgress,
1676
1662
  updateSubgraphStatus
1677
1663
  } from "@secondlayer/shared/db/queries/subgraphs";
@@ -2600,26 +2586,14 @@ async function refreshMatcher(db) {
2600
2586
 
2601
2587
  // src/runtime/block-processor.ts
2602
2588
  var routeCache = new Map;
2603
-
2604
- class ByoKeyUnavailableError extends Error {
2605
- constructor(subgraphName) {
2606
- super(`subgraph ${subgraphName} is BYO (database_url_enc set) but this process has no SECONDLAYER_SECRETS_KEY — the subgraph processor deliberately does not hold it (f072). Route BYO subgraphs to a process that does, or unset BYO.`);
2607
- this.name = "ByoKeyUnavailableError";
2608
- }
2609
- }
2610
2589
  async function resolveRoute(subgraphName, targetDb) {
2611
2590
  const cached = routeCache.get(subgraphName);
2612
2591
  if (cached)
2613
2592
  return cached;
2614
2593
  const row = await targetDb.selectFrom("subgraphs").selectAll().where("name", "=", subgraphName).executeTakeFirst();
2615
- const byo = row ? isByoSubgraph(row) : false;
2616
- if (row && byo && !secretsKeyAvailable()) {
2617
- throw new ByoKeyUnavailableError(subgraphName);
2618
- }
2619
2594
  const route = {
2620
2595
  schemaName: row?.schema_name ?? pgSchemaName(subgraphName),
2621
- dataDb: row && byo ? resolveSubgraphDb(row) : targetDb,
2622
- byo,
2596
+ dataDb: targetDb,
2623
2597
  sandboxWorkers: row?.sandbox_workers === true,
2624
2598
  handlerCode: row?.handler_code ?? null,
2625
2599
  version: row?.version ?? ""
@@ -2827,7 +2801,7 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
2827
2801
  await rewindLiveProgress(tx, subgraphName, blockHeight);
2828
2802
  } else {
2829
2803
  const advanced = await recordLiveProgress(tx, subgraphName, blockHeight);
2830
- if (!advanced && flushedWrites && !route.byo) {
2804
+ if (!advanced && flushedWrites) {
2831
2805
  throw new LiveCursorRaceLostError(subgraphName, blockHeight);
2832
2806
  }
2833
2807
  }
@@ -2836,122 +2810,79 @@ async function processBlock(subgraph, subgraphName, blockHeight, opts) {
2836
2810
  await recordSubgraphProcessed(tx, subgraphName, rr.processed, rr.errors, lastError);
2837
2811
  }
2838
2812
  };
2839
- if (route.byo) {
2840
- if (statusMode(opts)) {
2841
- const row = await targetDb.selectFrom("subgraphs").select("last_processed_block").where("name", "=", subgraphName).executeTakeFirst();
2842
- if (row && Number(row.last_processed_block) >= blockHeight) {
2843
- result.skipped = true;
2844
- return result;
2845
- }
2846
- } else if (opCursorMode(opts)) {
2847
- const om = opCursorMode(opts);
2848
- const row = await targetDb.selectFrom("subgraph_operations").select("cursor_block").where("id", "=", om.operationId).executeTakeFirst();
2849
- if (row?.cursor_block != null && Number(row.cursor_block) >= blockHeight) {
2850
- result.skipped = true;
2851
- return result;
2813
+ try {
2814
+ await targetDb.transaction().execute(async (tx) => {
2815
+ const opMode = opCursorMode(opts);
2816
+ const sm = statusMode(opts);
2817
+ const rewind = isReorgRewind(opts);
2818
+ if (sm) {
2819
+ const row = await tx.selectFrom("subgraphs").select("last_processed_block").where("name", "=", subgraphName).executeTakeFirst();
2820
+ if (row && Number(row.last_processed_block) >= blockHeight) {
2821
+ result.skipped = true;
2822
+ return;
2823
+ }
2824
+ } else if (opMode) {
2825
+ const row = await tx.selectFrom("subgraph_operations").select("cursor_block").where("id", "=", opMode.operationId).executeTakeFirst();
2826
+ if (row?.cursor_block != null && Number(row.cursor_block) >= blockHeight) {
2827
+ result.skipped = true;
2828
+ return;
2829
+ }
2830
+ } else if (!rewind) {
2831
+ const row = await tx.selectFrom("subgraphs").select("last_processed_block").where("name", "=", subgraphName).executeTakeFirst();
2832
+ if (row && Number(row.last_processed_block) >= blockHeight) {
2833
+ result.skipped = true;
2834
+ return;
2835
+ }
2852
2836
  }
2853
- }
2854
- let runResult = { processed: 0, errors: 0 };
2855
- let manifest;
2856
- await route.dataDb.transaction().execute(async (tx) => {
2857
- const ctx = new SubgraphContext(tx, schemaName, subgraph.schema, blockMeta, initialTx, true, journalEnabled(opts));
2837
+ const ctx = new SubgraphContext(tx, schemaName, subgraph.schema, blockMeta, initialTx, journalEnabled(opts));
2858
2838
  const handlerStart = performance.now();
2859
- runResult = await runHandlers(subgraph, matched, ctx);
2839
+ const runResult = sandboxEnabled({
2840
+ sandbox_workers: route.sandboxWorkers
2841
+ }) ? await runHandlersSandboxed({
2842
+ subgraphName,
2843
+ version: route.version,
2844
+ handlerCode: route.handlerCode,
2845
+ hostCtx: ctx,
2846
+ block: blockMeta,
2847
+ matched
2848
+ }) : await runHandlers(subgraph, matched, ctx);
2860
2849
  handlerMs = performance.now() - handlerStart;
2850
+ result.processed = runResult.processed;
2851
+ result.errors = runResult.errors;
2852
+ let flushedWrites = false;
2861
2853
  if (ctx.pendingOps > 0) {
2862
2854
  const flushStart = performance.now();
2863
- manifest = await ctx.flush();
2855
+ const manifest = await ctx.flush();
2856
+ flushedWrites = manifest.count > 0;
2857
+ if (manifest.count > 0) {
2858
+ await emitSubscriptionOutbox(tx, subgraphName, manifest, matcher, block.height);
2859
+ }
2864
2860
  flushMs = performance.now() - flushStart;
2865
2861
  }
2866
- });
2867
- result.processed = runResult.processed;
2868
- result.errors = runResult.errors;
2869
- await persistFactoryDiscoveries(schemaName, route.dataDb, blockHeight, discovered);
2870
- await targetDb.transaction().execute(async (tx) => {
2871
- if (manifest && manifest.count > 0) {
2872
- await emitSubscriptionOutbox(tx, subgraphName, manifest, matcher, block.height);
2873
- }
2874
- const byoSm = statusMode(opts);
2875
- const byoOm = opCursorMode(opts);
2876
- if (byoSm && manifest && manifest.count > 0) {
2877
- await updateSubgraphStatus(tx, subgraphName, byoSm.status, blockHeight);
2878
- } else if (byoOm && manifest && manifest.count > 0) {
2879
- await advanceOperationCursor(tx, byoOm.operationId, blockHeight);
2862
+ if (sm && flushedWrites) {
2863
+ await updateSubgraphStatus(tx, subgraphName, sm.status, blockHeight);
2864
+ } else if (opMode && flushedWrites) {
2865
+ const advanced = await advanceOperationCursor(tx, opMode.operationId, blockHeight);
2866
+ if (!advanced) {
2867
+ throw new CursorRaceLostError(opMode.operationId, blockHeight);
2868
+ }
2880
2869
  }
2881
- await applyProgress(tx, runResult, manifest ? manifest.count > 0 : false);
2870
+ await applyProgress(tx, runResult, flushedWrites);
2882
2871
  });
2883
- } else {
2884
- try {
2885
- await targetDb.transaction().execute(async (tx) => {
2886
- const opMode = opCursorMode(opts);
2887
- const sm = statusMode(opts);
2888
- const rewind = isReorgRewind(opts);
2889
- if (sm) {
2890
- const row = await tx.selectFrom("subgraphs").select("last_processed_block").where("name", "=", subgraphName).executeTakeFirst();
2891
- if (row && Number(row.last_processed_block) >= blockHeight) {
2892
- result.skipped = true;
2893
- return;
2894
- }
2895
- } else if (opMode) {
2896
- const row = await tx.selectFrom("subgraph_operations").select("cursor_block").where("id", "=", opMode.operationId).executeTakeFirst();
2897
- if (row?.cursor_block != null && Number(row.cursor_block) >= blockHeight) {
2898
- result.skipped = true;
2899
- return;
2900
- }
2901
- } else if (!rewind) {
2902
- const row = await tx.selectFrom("subgraphs").select("last_processed_block").where("name", "=", subgraphName).executeTakeFirst();
2903
- if (row && Number(row.last_processed_block) >= blockHeight) {
2904
- result.skipped = true;
2905
- return;
2906
- }
2907
- }
2908
- const ctx = new SubgraphContext(tx, schemaName, subgraph.schema, blockMeta, initialTx, false, journalEnabled(opts));
2909
- const handlerStart = performance.now();
2910
- const runResult = sandboxEnabled({
2911
- sandbox_workers: route.sandboxWorkers
2912
- }) ? await runHandlersSandboxed({
2913
- subgraphName,
2914
- version: route.version,
2915
- handlerCode: route.handlerCode,
2916
- hostCtx: ctx,
2917
- block: blockMeta,
2918
- matched
2919
- }) : await runHandlers(subgraph, matched, ctx);
2920
- handlerMs = performance.now() - handlerStart;
2921
- result.processed = runResult.processed;
2922
- result.errors = runResult.errors;
2923
- let flushedWrites = false;
2924
- if (ctx.pendingOps > 0) {
2925
- const flushStart = performance.now();
2926
- const manifest = await ctx.flush();
2927
- flushedWrites = manifest.count > 0;
2928
- if (manifest.count > 0) {
2929
- await emitSubscriptionOutbox(tx, subgraphName, manifest, matcher, block.height);
2930
- }
2931
- flushMs = performance.now() - flushStart;
2932
- }
2933
- if (sm && flushedWrites) {
2934
- await updateSubgraphStatus(tx, subgraphName, sm.status, blockHeight);
2935
- } else if (opMode && flushedWrites) {
2936
- const advanced = await advanceOperationCursor(tx, opMode.operationId, blockHeight);
2937
- if (!advanced) {
2938
- throw new CursorRaceLostError(opMode.operationId, blockHeight);
2939
- }
2940
- }
2941
- await applyProgress(tx, runResult, flushedWrites);
2872
+ } catch (err) {
2873
+ if (err instanceof CursorRaceLostError || err instanceof LiveCursorRaceLostError) {
2874
+ logger7.warn("cursor race lost — block already covered", {
2875
+ subgraph: subgraphName,
2876
+ blockHeight,
2877
+ error: err.message
2942
2878
  });
2943
- } catch (err) {
2944
- if (err instanceof CursorRaceLostError || err instanceof LiveCursorRaceLostError) {
2945
- logger7.warn("cursor race lost — block already covered", {
2946
- subgraph: subgraphName,
2947
- blockHeight,
2948
- error: err.message
2949
- });
2950
- result.skipped = true;
2951
- return result;
2952
- }
2953
- throw err;
2879
+ result.skipped = true;
2880
+ return result;
2954
2881
  }
2882
+ throw err;
2883
+ }
2884
+ if (!result.skipped) {
2885
+ await persistFactoryDiscoveries(schemaName, route.dataDb, blockHeight, discovered);
2955
2886
  }
2956
2887
  const totalMs = performance.now() - blockStart;
2957
2888
  if (!result.skipped) {
@@ -2992,9 +2923,8 @@ export {
2992
2923
  processBlockWithRetry,
2993
2924
  processBlock,
2994
2925
  invalidateSubgraphRoute,
2995
- ByoKeyUnavailableError,
2996
2926
  BLOCK_RETRY_DELAYS_MS
2997
2927
  };
2998
2928
 
2999
- //# debugId=12259A1169CD0EF964756E2164756E21
2929
+ //# debugId=94D930A6B3A998FE64756E2164756E21
3000
2930
  //# sourceMappingURL=block-processor.js.map