@secondlayer/cli 22.0.1 → 22.1.0
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/cli.js +172 -8
- package/dist/cli.js.map +6 -5
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -29488,7 +29488,7 @@ var init_git_status = () => {};
|
|
|
29488
29488
|
|
|
29489
29489
|
// ../../node_modules/typescript/lib/typescript.js
|
|
29490
29490
|
var require_typescript = __commonJS(function(exports, module) {
|
|
29491
|
-
var __dirname = "/Users/ryan/projects/secondlayer/node_modules/typescript/lib", __filename = "/Users/ryan/projects/secondlayer/node_modules/typescript/lib/typescript.js";
|
|
29491
|
+
var __dirname = "/Users/ryan/projects/secondlayer/.claude/worktrees/rel313/node_modules/typescript/lib", __filename = "/Users/ryan/projects/secondlayer/.claude/worktrees/rel313/node_modules/typescript/lib/typescript.js";
|
|
29492
29492
|
/*! *****************************************************************************
|
|
29493
29493
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
29494
29494
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
@@ -202711,7 +202711,7 @@ var {
|
|
|
202711
202711
|
// package.json
|
|
202712
202712
|
var package_default = {
|
|
202713
202713
|
name: "@secondlayer/cli",
|
|
202714
|
-
version: "22.0
|
|
202714
|
+
version: "22.1.0",
|
|
202715
202715
|
description: "Run a Stacks index on your own hardware — set it up, restore verified history, and keep it current.",
|
|
202716
202716
|
repository: {
|
|
202717
202717
|
type: "git",
|
|
@@ -204184,6 +204184,126 @@ import {
|
|
|
204184
204184
|
reportVerify
|
|
204185
204185
|
} from "@secondlayer/shared/coverage";
|
|
204186
204186
|
import { getDb as getDb3 } from "@secondlayer/shared/db";
|
|
204187
|
+
|
|
204188
|
+
// src/lib/archive-heights.ts
|
|
204189
|
+
import {
|
|
204190
|
+
PerHeightDigestAccumulator
|
|
204191
|
+
} from "@secondlayer/shared/archive/per-height-digest";
|
|
204192
|
+
import {
|
|
204193
|
+
streamHeightDigests
|
|
204194
|
+
} from "@secondlayer/shared/archive/semantic-digest-builder";
|
|
204195
|
+
var PART_FOR_DATASET = {
|
|
204196
|
+
blocks: "block",
|
|
204197
|
+
transactions: "transactions",
|
|
204198
|
+
events: "events"
|
|
204199
|
+
};
|
|
204200
|
+
async function localPerHeightDigests(db, fromBlock, toBlock, datasets = ["blocks", "transactions", "events"]) {
|
|
204201
|
+
const accumulator = new PerHeightDigestAccumulator;
|
|
204202
|
+
for await (const { height, digest } of streamHeightDigests(db, "blocks", fromBlock, toBlock)) {
|
|
204203
|
+
accumulator.setBlockDigest(height, digest);
|
|
204204
|
+
}
|
|
204205
|
+
if (datasets.includes("transactions")) {
|
|
204206
|
+
for await (const { height, digest } of streamHeightDigests(db, "transactions", fromBlock, toBlock)) {
|
|
204207
|
+
accumulator.appendTransactionDigest(height, digest);
|
|
204208
|
+
}
|
|
204209
|
+
}
|
|
204210
|
+
if (datasets.includes("events")) {
|
|
204211
|
+
for await (const { height, digest } of streamHeightDigests(db, "events", fromBlock, toBlock)) {
|
|
204212
|
+
accumulator.appendEventDigest(height, digest);
|
|
204213
|
+
}
|
|
204214
|
+
}
|
|
204215
|
+
const rows = new Map;
|
|
204216
|
+
for (const row of accumulator.drain(fromBlock, toBlock)) {
|
|
204217
|
+
rows.set(row.height, row);
|
|
204218
|
+
}
|
|
204219
|
+
return rows;
|
|
204220
|
+
}
|
|
204221
|
+
function sidecarsCovering(digestIndex, fromBlock, toBlock) {
|
|
204222
|
+
return (digestIndex ?? []).filter((p) => p.from_block <= toBlock && p.to_block >= fromBlock);
|
|
204223
|
+
}
|
|
204224
|
+
async function fetchSidecarRows(reference, partition) {
|
|
204225
|
+
const bytes = await fetchVerifiedPartition(reference, partition);
|
|
204226
|
+
const rows = [];
|
|
204227
|
+
for await (const raw of readPartitionRows(bytes, `digests-${partition.from_block}-${partition.to_block}`)) {
|
|
204228
|
+
const row = raw;
|
|
204229
|
+
rows.push({
|
|
204230
|
+
height: Number(row.height),
|
|
204231
|
+
block_digest: String(row.block_digest),
|
|
204232
|
+
transactions_rollup: row.transactions_rollup == null ? null : String(row.transactions_rollup),
|
|
204233
|
+
events_rollup: row.events_rollup == null ? null : String(row.events_rollup)
|
|
204234
|
+
});
|
|
204235
|
+
}
|
|
204236
|
+
return rows;
|
|
204237
|
+
}
|
|
204238
|
+
function compareHeights(params) {
|
|
204239
|
+
const { dataset, fromBlock, toBlock, local, archive, covered } = params;
|
|
204240
|
+
const inCoverage = (h) => covered.some((c) => h >= c.from_block && h <= c.to_block);
|
|
204241
|
+
const heights = new Set;
|
|
204242
|
+
for (const h of archive.keys())
|
|
204243
|
+
heights.add(h);
|
|
204244
|
+
for (const h of local.keys())
|
|
204245
|
+
if (inCoverage(h))
|
|
204246
|
+
heights.add(h);
|
|
204247
|
+
const out = [];
|
|
204248
|
+
for (const height of [...heights].sort((a, b) => a - b)) {
|
|
204249
|
+
if (height < fromBlock || height > toBlock)
|
|
204250
|
+
continue;
|
|
204251
|
+
const mine = local.get(height);
|
|
204252
|
+
const theirs = archive.get(height);
|
|
204253
|
+
if (!mine && theirs) {
|
|
204254
|
+
out.push({ height, parts: ["missing-local"] });
|
|
204255
|
+
} else if (mine && !theirs) {
|
|
204256
|
+
out.push({ height, parts: ["missing-archive"] });
|
|
204257
|
+
} else if (mine && theirs && !partsMatch(dataset, mine, theirs)) {
|
|
204258
|
+
out.push({ height, parts: [PART_FOR_DATASET[dataset]] });
|
|
204259
|
+
}
|
|
204260
|
+
}
|
|
204261
|
+
return out;
|
|
204262
|
+
}
|
|
204263
|
+
function partsMatch(dataset, a, b) {
|
|
204264
|
+
if (dataset === "blocks")
|
|
204265
|
+
return a.block_digest === b.block_digest;
|
|
204266
|
+
if (dataset === "transactions") {
|
|
204267
|
+
return a.transactions_rollup === b.transactions_rollup;
|
|
204268
|
+
}
|
|
204269
|
+
return a.events_rollup === b.events_rollup;
|
|
204270
|
+
}
|
|
204271
|
+
async function divergentHeightsForRange(params) {
|
|
204272
|
+
const { db, reference, dataset, fromBlock, toBlock } = params;
|
|
204273
|
+
const sidecars = sidecarsCovering(params.digestIndex, fromBlock, toBlock);
|
|
204274
|
+
if (sidecars.length === 0)
|
|
204275
|
+
return null;
|
|
204276
|
+
const archive = new Map;
|
|
204277
|
+
for (const sidecar of sidecars) {
|
|
204278
|
+
for (const row of await fetchSidecarRows(reference, sidecar)) {
|
|
204279
|
+
archive.set(row.height, row);
|
|
204280
|
+
}
|
|
204281
|
+
}
|
|
204282
|
+
const local = await localPerHeightDigests(db, fromBlock, toBlock, [dataset]);
|
|
204283
|
+
return compareHeights({
|
|
204284
|
+
dataset,
|
|
204285
|
+
fromBlock,
|
|
204286
|
+
toBlock,
|
|
204287
|
+
local,
|
|
204288
|
+
archive,
|
|
204289
|
+
covered: sidecars
|
|
204290
|
+
});
|
|
204291
|
+
}
|
|
204292
|
+
function mergeRepairRanges(ranges) {
|
|
204293
|
+
const sorted = [...ranges].sort((a, b) => a.from_block - b.from_block || a.to_block - b.to_block);
|
|
204294
|
+
const merged = [];
|
|
204295
|
+
for (const range of sorted) {
|
|
204296
|
+
const last = merged[merged.length - 1];
|
|
204297
|
+
if (last && range.from_block <= last.to_block + 1) {
|
|
204298
|
+
last.to_block = Math.max(last.to_block, range.to_block);
|
|
204299
|
+
} else {
|
|
204300
|
+
merged.push({ from_block: range.from_block, to_block: range.to_block });
|
|
204301
|
+
}
|
|
204302
|
+
}
|
|
204303
|
+
return merged;
|
|
204304
|
+
}
|
|
204305
|
+
|
|
204306
|
+
// src/commands/verify.ts
|
|
204187
204307
|
init_output();
|
|
204188
204308
|
init_resolve_auth();
|
|
204189
204309
|
|
|
@@ -204578,6 +204698,7 @@ function parseHeight3(value, flag) {
|
|
|
204578
204698
|
}
|
|
204579
204699
|
return parsed;
|
|
204580
204700
|
}
|
|
204701
|
+
var MAX_HEIGHTS_SHOWN = 20;
|
|
204581
204702
|
function statusLabel(status) {
|
|
204582
204703
|
if (status === "match")
|
|
204583
204704
|
return green("ok");
|
|
@@ -204616,9 +204737,10 @@ Exit codes:
|
|
|
204616
204737
|
envPem: process.env.ARCHIVE_SIGNING_PUBLIC_KEY ?? process.env.STREAMS_SIGNING_PUBLIC_KEY,
|
|
204617
204738
|
allowHostedApi: !isOssMode()
|
|
204618
204739
|
});
|
|
204619
|
-
const
|
|
204740
|
+
const loaded = await loadReference(opts.against, {
|
|
204620
204741
|
publicKeyPem: publicKey
|
|
204621
204742
|
});
|
|
204743
|
+
const { manifest, origin } = loaded;
|
|
204622
204744
|
const signature = checkSignature(manifest, publicKey, !!opts.insecure);
|
|
204623
204745
|
if (!signature.verified && !opts.insecure) {
|
|
204624
204746
|
printError(`Cannot trust the reference: ${signature.reason}.`, {
|
|
@@ -204751,6 +204873,30 @@ Exit codes:
|
|
|
204751
204873
|
}))
|
|
204752
204874
|
];
|
|
204753
204875
|
const diverged = all.filter((c) => c.status !== "match");
|
|
204876
|
+
const digestIndex = manifest.digest_index;
|
|
204877
|
+
const heightNotes = [];
|
|
204878
|
+
if (diverged.length > 0 && !digestIndex?.length) {
|
|
204879
|
+
heightNotes.push("This snapshot has no per-height digests; exact diverging heights need a newer snapshot.");
|
|
204880
|
+
} else {
|
|
204881
|
+
for (const range of diverged) {
|
|
204882
|
+
try {
|
|
204883
|
+
const heights = await divergentHeightsForRange({
|
|
204884
|
+
db,
|
|
204885
|
+
reference: loaded,
|
|
204886
|
+
digestIndex,
|
|
204887
|
+
dataset: range.dataset,
|
|
204888
|
+
fromBlock: range.from_block,
|
|
204889
|
+
toBlock: range.to_block
|
|
204890
|
+
});
|
|
204891
|
+
if (heights)
|
|
204892
|
+
range.divergent_heights = heights;
|
|
204893
|
+
else
|
|
204894
|
+
heightNotes.push(`No per-height digests cover ${range.from_block}-${range.to_block}.`);
|
|
204895
|
+
} catch (err) {
|
|
204896
|
+
heightNotes.push(`Could not narrow ${range.from_block}-${range.to_block} to heights: ${err instanceof Error ? err.message : String(err)}`);
|
|
204897
|
+
}
|
|
204898
|
+
}
|
|
204899
|
+
}
|
|
204754
204900
|
const verdict = reportVerify({
|
|
204755
204901
|
target,
|
|
204756
204902
|
mode,
|
|
@@ -204763,7 +204909,8 @@ Exit codes:
|
|
|
204763
204909
|
signature_verified: signature.verified,
|
|
204764
204910
|
ranges_checked: all.length,
|
|
204765
204911
|
semantic_checks: semanticChecks.length,
|
|
204766
|
-
divergent_ranges: diverged
|
|
204912
|
+
divergent_ranges: diverged,
|
|
204913
|
+
...heightNotes.length > 0 ? { note: heightNotes.join(" ") } : {}
|
|
204767
204914
|
};
|
|
204768
204915
|
output({
|
|
204769
204916
|
json: opts.json,
|
|
@@ -204783,11 +204930,28 @@ Exit codes:
|
|
|
204783
204930
|
String(d.expected_rows),
|
|
204784
204931
|
String(d.actual_rows)
|
|
204785
204932
|
])));
|
|
204933
|
+
for (const range of diverged) {
|
|
204934
|
+
const heights = range.divergent_heights;
|
|
204935
|
+
if (!heights)
|
|
204936
|
+
continue;
|
|
204937
|
+
console.error("");
|
|
204938
|
+
console.error(`${range.from_block}-${range.to_block} ${range.dataset}: ${heights.length} diverging height${heights.length === 1 ? "" : "s"}`);
|
|
204939
|
+
for (const h of heights.slice(0, MAX_HEIGHTS_SHOWN)) {
|
|
204940
|
+
console.error(` ${h.height} ${h.parts.join(", ")}`);
|
|
204941
|
+
}
|
|
204942
|
+
if (heights.length > MAX_HEIGHTS_SHOWN) {
|
|
204943
|
+
console.error(dim(` and ${heights.length - MAX_HEIGHTS_SHOWN} more (see --json)`));
|
|
204944
|
+
}
|
|
204945
|
+
}
|
|
204946
|
+
if (heightNotes.length > 0) {
|
|
204947
|
+
console.error("");
|
|
204948
|
+
for (const line of heightNotes)
|
|
204949
|
+
console.error(dim(` ${line}`));
|
|
204950
|
+
}
|
|
204786
204951
|
console.error("");
|
|
204787
204952
|
console.error(dim("These ranges hold different data than the signed archive. Repair with:"));
|
|
204788
|
-
const
|
|
204789
|
-
|
|
204790
|
-
console.error(dim(` secondlayer repair --from-block ${first.from_block} --to-block ${first.to_block}`));
|
|
204953
|
+
for (const range of mergeRepairRanges(diverged)) {
|
|
204954
|
+
console.error(dim(` secondlayer repair --from-block ${range.from_block} --to-block ${range.to_block}`));
|
|
204791
204955
|
}
|
|
204792
204956
|
}
|
|
204793
204957
|
});
|
|
@@ -208690,5 +208854,5 @@ registerCreditsCommand(program);
|
|
|
208690
208854
|
registerArchiveCommand(program);
|
|
208691
208855
|
program.parse();
|
|
208692
208856
|
|
|
208693
|
-
//# debugId=
|
|
208857
|
+
//# debugId=32F86A2D9F7E084964756E2164756E21
|
|
208694
208858
|
//# sourceMappingURL=cli.js.map
|