@secondlayer/subgraphs 4.1.1 → 4.1.3
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.
- package/dist/src/index.js +111 -3
- package/dist/src/index.js.map +7 -6
- package/dist/src/runtime/block-processor.js +3 -1
- package/dist/src/runtime/block-processor.js.map +3 -3
- package/dist/src/runtime/catchup.js +88 -2
- package/dist/src/runtime/catchup.js.map +7 -6
- package/dist/src/runtime/processor.js +111 -3
- package/dist/src/runtime/processor.js.map +7 -6
- package/dist/src/runtime/reindex.js +111 -3
- package/dist/src/runtime/reindex.js.map +7 -6
- package/dist/src/runtime/reorg.js +88 -2
- package/dist/src/runtime/reorg.js.map +6 -5
- package/dist/src/runtime/replay.js +68 -4
- package/dist/src/runtime/replay.js.map +6 -5
- package/dist/src/service.js +111 -3
- package/dist/src/service.js.map +7 -6
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -2290,6 +2290,8 @@ function indexEventTypesForFilterTypes(filterTypes) {
|
|
|
2290
2290
|
return [...types];
|
|
2291
2291
|
}
|
|
2292
2292
|
function referencedIndexEventTypes(subgraph) {
|
|
2293
|
+
if (!subgraph.sources)
|
|
2294
|
+
return [];
|
|
2293
2295
|
return indexEventTypesForFilterTypes(sourceFilters(subgraph).map((f) => f.type));
|
|
2294
2296
|
}
|
|
2295
2297
|
function isStreamsIndexEligible(subgraph) {
|
|
@@ -3407,6 +3409,66 @@ function startCatchUpLeader(opts = {}) {
|
|
|
3407
3409
|
});
|
|
3408
3410
|
}
|
|
3409
3411
|
|
|
3412
|
+
// src/runtime/decoder-bound.ts
|
|
3413
|
+
import { decodeStreamsCursor, isEmptyRangeCursor } from "@secondlayer/shared";
|
|
3414
|
+
import { getSourceDb as getSourceDb3 } from "@secondlayer/shared/db";
|
|
3415
|
+
function decoderNameForEventType(indexEventType) {
|
|
3416
|
+
return `decode.${indexEventType}.v1`;
|
|
3417
|
+
}
|
|
3418
|
+
function decoderNamesForIndexEventTypes(eventTypes) {
|
|
3419
|
+
return eventTypes.map(decoderNameForEventType);
|
|
3420
|
+
}
|
|
3421
|
+
function decoderNamesForSubgraph(subgraph) {
|
|
3422
|
+
return decoderNamesForIndexEventTypes(referencedIndexEventTypes(subgraph));
|
|
3423
|
+
}
|
|
3424
|
+
function usesDecodedIndexPlane(subgraph) {
|
|
3425
|
+
return process.env.SUBGRAPH_SOURCE === "streams-index" && isStreamsIndexEligible(subgraph);
|
|
3426
|
+
}
|
|
3427
|
+
function committedHeight(cursor) {
|
|
3428
|
+
if (!cursor)
|
|
3429
|
+
return null;
|
|
3430
|
+
try {
|
|
3431
|
+
const decoded = decodeStreamsCursor(cursor);
|
|
3432
|
+
if (isEmptyRangeCursor(decoded))
|
|
3433
|
+
return decoded.block_height;
|
|
3434
|
+
return Math.max(0, decoded.block_height - 1);
|
|
3435
|
+
} catch {
|
|
3436
|
+
return null;
|
|
3437
|
+
}
|
|
3438
|
+
}
|
|
3439
|
+
async function decoderBoundTip(decoderNames, opts) {
|
|
3440
|
+
if (decoderNames.length === 0)
|
|
3441
|
+
return { kind: "unbounded" };
|
|
3442
|
+
const sourceDb = opts?.sourceDb ?? getSourceDb3();
|
|
3443
|
+
const rows = await sourceDb.selectFrom("decoder_checkpoints").select(["decoder_name", "last_cursor"]).where("decoder_name", "in", decoderNames).execute();
|
|
3444
|
+
const byName = new Map(rows.map((r) => [r.decoder_name, r.last_cursor]));
|
|
3445
|
+
const missing = [];
|
|
3446
|
+
const heights = [];
|
|
3447
|
+
for (const name of decoderNames) {
|
|
3448
|
+
const height = committedHeight(byName.get(name));
|
|
3449
|
+
if (height === null)
|
|
3450
|
+
missing.push(name);
|
|
3451
|
+
else
|
|
3452
|
+
heights.push(height);
|
|
3453
|
+
}
|
|
3454
|
+
if (missing.length > 0)
|
|
3455
|
+
return { kind: "stall", missing };
|
|
3456
|
+
return { kind: "height", height: Math.min(...heights) };
|
|
3457
|
+
}
|
|
3458
|
+
async function boundSourceTip(rawTip, decoderNames, opts) {
|
|
3459
|
+
const bound = await decoderBoundTip(decoderNames, opts);
|
|
3460
|
+
if (bound.kind === "stall")
|
|
3461
|
+
return { ok: false, missing: bound.missing };
|
|
3462
|
+
if (bound.kind === "unbounded") {
|
|
3463
|
+
return { ok: true, tip: rawTip, floor: null };
|
|
3464
|
+
}
|
|
3465
|
+
return {
|
|
3466
|
+
ok: true,
|
|
3467
|
+
tip: Math.min(rawTip, bound.height),
|
|
3468
|
+
floor: bound.height
|
|
3469
|
+
};
|
|
3470
|
+
}
|
|
3471
|
+
|
|
3410
3472
|
// src/runtime/catchup.ts
|
|
3411
3473
|
var LOG_INTERVAL = 1000;
|
|
3412
3474
|
var STANDARD_CATCHUP_BATCH_CONFIG = {
|
|
@@ -3517,7 +3579,31 @@ async function catchUpSubgraph(subgraph, subgraphName) {
|
|
|
3517
3579
|
if (!subgraphRow)
|
|
3518
3580
|
return 0;
|
|
3519
3581
|
const lastProcessedBlock = Number(subgraphRow.last_processed_block);
|
|
3520
|
-
const
|
|
3582
|
+
const rawTip = await source.getTip();
|
|
3583
|
+
if (rawTip <= 0)
|
|
3584
|
+
return 0;
|
|
3585
|
+
let chainTip = rawTip;
|
|
3586
|
+
if (usesDecodedIndexPlane(subgraph)) {
|
|
3587
|
+
const bound = await boundSourceTip(rawTip, decoderNamesForSubgraph(subgraph));
|
|
3588
|
+
if (!bound.ok) {
|
|
3589
|
+
logger8.warn("Subgraph catch-up stalled: missing decoder checkpoint", {
|
|
3590
|
+
event: "subgraph_catchup_decoder_stall",
|
|
3591
|
+
subgraph: subgraphName,
|
|
3592
|
+
missing: bound.missing
|
|
3593
|
+
});
|
|
3594
|
+
return 0;
|
|
3595
|
+
}
|
|
3596
|
+
if (bound.floor !== null && bound.floor < rawTip) {
|
|
3597
|
+
logger8.debug("Subgraph catch-up tip bounded by decoder progress", {
|
|
3598
|
+
event: "subgraph_catchup_decoder_floor",
|
|
3599
|
+
subgraph: subgraphName,
|
|
3600
|
+
rawTip,
|
|
3601
|
+
floor: bound.floor,
|
|
3602
|
+
tip: bound.tip
|
|
3603
|
+
});
|
|
3604
|
+
}
|
|
3605
|
+
chainTip = bound.tip;
|
|
3606
|
+
}
|
|
3521
3607
|
if (chainTip <= 0 || lastProcessedBlock >= chainTip)
|
|
3522
3608
|
return 0;
|
|
3523
3609
|
const subgraphStart = Number(subgraphRow.start_block) || 1;
|
|
@@ -3980,7 +4066,29 @@ async function processBlockRange(def, opts) {
|
|
|
3980
4066
|
async function resolveBlockRange(source, def, opts) {
|
|
3981
4067
|
const definitionStart = def.startBlock ?? 1;
|
|
3982
4068
|
const fromBlock = opts?.startBlockFloor != null ? Math.max(definitionStart, opts.startBlockFloor) : definitionStart;
|
|
3983
|
-
|
|
4069
|
+
const rawTip = await source.getTip();
|
|
4070
|
+
if (!usesDecodedIndexPlane(def)) {
|
|
4071
|
+
return { fromBlock, toBlock: rawTip };
|
|
4072
|
+
}
|
|
4073
|
+
const bound = await boundSourceTip(rawTip, decoderNamesForSubgraph(def));
|
|
4074
|
+
if (!bound.ok) {
|
|
4075
|
+
logger10.warn("Reindex stalled: missing decoder checkpoint", {
|
|
4076
|
+
event: "subgraph_reindex_decoder_stall",
|
|
4077
|
+
subgraph: def.name,
|
|
4078
|
+
missing: bound.missing
|
|
4079
|
+
});
|
|
4080
|
+
throw new Error(`Reindex stalled: missing decoder checkpoint (${bound.missing.join(", ")})`);
|
|
4081
|
+
}
|
|
4082
|
+
if (bound.floor !== null && bound.floor < rawTip) {
|
|
4083
|
+
logger10.debug("Reindex tip bounded by decoder progress", {
|
|
4084
|
+
event: "subgraph_reindex_decoder_floor",
|
|
4085
|
+
subgraph: def.name,
|
|
4086
|
+
rawTip,
|
|
4087
|
+
floor: bound.floor,
|
|
4088
|
+
tip: bound.tip
|
|
4089
|
+
});
|
|
4090
|
+
}
|
|
4091
|
+
return { fromBlock, toBlock: bound.tip };
|
|
3984
4092
|
}
|
|
3985
4093
|
async function clearReindexMetadata(db, subgraphName) {
|
|
3986
4094
|
await db.updateTable("subgraphs").set({ reindex_from_block: null, reindex_to_block: null }).where("name", "=", subgraphName).execute();
|
|
@@ -5438,5 +5546,5 @@ export {
|
|
|
5438
5546
|
ChainReadError
|
|
5439
5547
|
};
|
|
5440
5548
|
|
|
5441
|
-
//# debugId=
|
|
5549
|
+
//# debugId=5A8D4A3C8F2C6DFE64756E2164756E21
|
|
5442
5550
|
//# sourceMappingURL=index.js.map
|