@mikeargento/bitgraph-player 0.2.1 → 0.4.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/README.md +40 -0
- package/SPEC.md +95 -6
- package/dist/__tests__/check.test.d.ts +2 -0
- package/dist/__tests__/check.test.d.ts.map +1 -0
- package/dist/__tests__/check.test.js +358 -0
- package/dist/__tests__/check.test.js.map +1 -0
- package/dist/__tests__/sig-v2.test.d.ts +2 -0
- package/dist/__tests__/sig-v2.test.d.ts.map +1 -0
- package/dist/__tests__/sig-v2.test.js +266 -0
- package/dist/__tests__/sig-v2.test.js.map +1 -0
- package/dist/check.d.ts +156 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +640 -0
- package/dist/check.js.map +1 -0
- package/dist/cli.js +84 -15
- package/dist/cli.js.map +1 -1
- package/dist/evaluate.d.ts +8 -21
- package/dist/evaluate.d.ts.map +1 -1
- package/dist/evaluate.js +93 -2
- package/dist/evaluate.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/play.d.ts +12 -2
- package/dist/play.d.ts.map +1 -1
- package/dist/play.js +39 -4
- package/dist/play.js.map +1 -1
- package/dist/rule.d.ts +0 -13
- package/dist/rule.d.ts.map +1 -1
- package/dist/rule.js +84 -8
- package/dist/rule.js.map +1 -1
- package/dist/sig.d.ts +38 -0
- package/dist/sig.d.ts.map +1 -0
- package/dist/sig.js +154 -0
- package/dist/sig.js.map +1 -0
- package/dist/types.d.ts +21 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/verdict.d.ts +1 -1
- package/dist/verdict.d.ts.map +1 -1
- package/dist/verdict.js +17 -2
- package/dist/verdict.js.map +1 -1
- package/dist-web/verify.html +159 -0
- package/package.json +8 -3
- package/src/__tests__/check.test.ts +417 -0
- package/src/__tests__/fixtures/export-random-043/ethereum-anchors/anchor-after-witness.json +6 -0
- package/src/__tests__/fixtures/export-random-043/ethereum-anchors/anchor-after.json +43 -0
- package/src/__tests__/fixtures/export-random-043/ethereum-anchors/anchor-before-witness.json +6 -0
- package/src/__tests__/fixtures/export-random-043/ethereum-anchors/anchor-before.json +47 -0
- package/src/__tests__/fixtures/export-random-043/proof.json +38 -0
- package/src/__tests__/fixtures/export-random-043/random-043.txt +1 -0
- package/src/__tests__/sig-v2.test.ts +315 -0
- package/src/check.ts +873 -0
- package/src/cli.ts +82 -16
- package/src/evaluate.ts +107 -2
- package/src/index.ts +9 -2
- package/src/play.ts +43 -5
- package/src/rule.ts +93 -9
- package/src/sig.ts +170 -0
- package/src/types.ts +21 -4
- package/src/verdict.ts +18 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikeargento/bitgraph-player",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Deterministic evaluation of causal rules over BitGraph proof bundles: a pure function from (rule, verified evidence) to a reproducible verdict.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
19
|
"dist",
|
|
20
|
+
"dist-web",
|
|
20
21
|
"src",
|
|
21
22
|
"SPEC.md",
|
|
22
23
|
"README.md",
|
|
@@ -26,17 +27,21 @@
|
|
|
26
27
|
"build": "tsc",
|
|
27
28
|
"prepack": "tsc",
|
|
28
29
|
"typecheck": "tsc --noEmit",
|
|
29
|
-
"test": "tsc && node --test \"dist/__tests__/*.test.js\""
|
|
30
|
+
"test": "tsc && node --test \"dist/__tests__/*.test.js\"",
|
|
31
|
+
"build:web": "node scripts/build-verify-html.mjs --out ../folder/src/verify.html",
|
|
32
|
+
"typecheck:web": "tsc -p web/tsconfig.json"
|
|
30
33
|
},
|
|
31
34
|
"engines": {
|
|
32
35
|
"node": ">=20"
|
|
33
36
|
},
|
|
34
37
|
"dependencies": {
|
|
35
|
-
"@mikeargento/bitgraph-audit": "^0.
|
|
38
|
+
"@mikeargento/bitgraph-audit": "^0.2.0",
|
|
36
39
|
"@mikeargento/bitgraph-verify": "^1.1.2"
|
|
37
40
|
},
|
|
38
41
|
"devDependencies": {
|
|
39
42
|
"@types/node": "^20.0.0",
|
|
43
|
+
"buffer": "^6.0.3",
|
|
44
|
+
"esbuild": "^0.27.0",
|
|
40
45
|
"typescript": "^5.4.0"
|
|
41
46
|
}
|
|
42
47
|
}
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
// Copyright (c) 2024-2026 Mike Argento. Licensed under the MIT License. See LICENSE.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `check` tests.
|
|
5
|
+
*
|
|
6
|
+
* The real fixture is a genuine export from the production ledger: a
|
|
7
|
+
* 685-byte random text file, its proof (real Ed25519 signature, real AWS
|
|
8
|
+
* Nitro attestation, enclave v5 measurement), both bounding anchors, and
|
|
9
|
+
* both block-header witnesses. Copied verbatim from a BitGraph Folder
|
|
10
|
+
* export; read-only here, no ledger writes, no network.
|
|
11
|
+
*
|
|
12
|
+
* The parity test is the one that matters most: the same bundle ingested
|
|
13
|
+
* from disk (the CLI's path) and from memory (the browser page's path)
|
|
14
|
+
* must produce byte-identical reports, or the two fronts have drifted.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { describe, it, before, after } from "node:test";
|
|
18
|
+
import * as assert from "node:assert/strict";
|
|
19
|
+
import { spawnSync } from "node:child_process";
|
|
20
|
+
import { cp, mkdtemp, readFile, rm, writeFile, readdir } from "node:fs/promises";
|
|
21
|
+
import { tmpdir } from "node:os";
|
|
22
|
+
import { join, relative } from "node:path";
|
|
23
|
+
import { fileURLToPath } from "node:url";
|
|
24
|
+
import { ingestBundle, ingestEntries } from "@mikeargento/bitgraph-audit";
|
|
25
|
+
import type { AuditResult, BundleEntrySource } from "@mikeargento/bitgraph-audit";
|
|
26
|
+
import { buildCheckReport, checkIngest, renderCheckText, serializeCheckReport, KNOWN_ENCLAVE_MEASUREMENTS } from "../check.js";
|
|
27
|
+
import type { CheckReport } from "../check.js";
|
|
28
|
+
import { PLAYER_VERSION } from "../verdict.js";
|
|
29
|
+
import { digestFor, makeAudit } from "./fixtures.js";
|
|
30
|
+
|
|
31
|
+
const FIXTURE = fileURLToPath(new URL("../../src/__tests__/fixtures/export-random-043", import.meta.url));
|
|
32
|
+
const CLI_PATH = fileURLToPath(new URL("../cli.js", import.meta.url));
|
|
33
|
+
|
|
34
|
+
async function walk(root: string, rel = ""): Promise<string[]> {
|
|
35
|
+
const out: string[] = [];
|
|
36
|
+
const dir = rel === "" ? root : join(root, rel);
|
|
37
|
+
for (const entry of await readdir(dir, { withFileTypes: true })) {
|
|
38
|
+
const r = rel === "" ? entry.name : `${rel}/${entry.name}`;
|
|
39
|
+
if (entry.isDirectory()) out.push(...(await walk(root, r)));
|
|
40
|
+
else if (entry.isFile()) out.push(r);
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function memoryEntriesOf(root: string): Promise<BundleEntrySource[]> {
|
|
46
|
+
const paths = await walk(root);
|
|
47
|
+
return paths.map((p) => ({
|
|
48
|
+
path: p,
|
|
49
|
+
open: () => readFile(join(root, ...p.split("/"))).then((b) => new Uint8Array(b)),
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Fill the audit sections makeAudit leaves empty so buildCheckReport can run over synthetic input. */
|
|
54
|
+
function complete(audit: AuditResult, overrides: Partial<AuditResult> = {}): AuditResult {
|
|
55
|
+
const a = audit as unknown as Record<string, unknown>;
|
|
56
|
+
return {
|
|
57
|
+
...audit,
|
|
58
|
+
anomalies: { anomalies: [], divergences: [], boundaryEntryPoints: [] },
|
|
59
|
+
authorities: { groups: [], anomalies: [], sharedSignersAcrossEpochs: [] },
|
|
60
|
+
anchors: { anchors: [], metadataOnlyProofHashes: [], findings: [] },
|
|
61
|
+
witnesses: { outcomes: [], findings: [] },
|
|
62
|
+
attestations: {
|
|
63
|
+
records: [],
|
|
64
|
+
findings: [],
|
|
65
|
+
counts: {
|
|
66
|
+
proofsWithDeclaredMeasurement: 0,
|
|
67
|
+
proofsWithDocument: 0,
|
|
68
|
+
documentsValidated: 0,
|
|
69
|
+
documentsFailed: 0,
|
|
70
|
+
pcr0Matches: 0,
|
|
71
|
+
pcr0Mismatches: 0,
|
|
72
|
+
userDataBound: 0,
|
|
73
|
+
userDataUnbound: 0,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
...(a["temporal"] !== undefined ? {} : {}),
|
|
77
|
+
...overrides,
|
|
78
|
+
} as AuditResult;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
describe("check: real export fixture (disk)", () => {
|
|
82
|
+
let report: CheckReport;
|
|
83
|
+
before(async () => {
|
|
84
|
+
report = await checkIngest(await ingestBundle(FIXTURE));
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("is TRUE end to end: file, signature, attestation, enclave, both anchors, both witnesses", () => {
|
|
88
|
+
assert.equal(report.check, "bitgraph-check/1");
|
|
89
|
+
assert.equal(report.result, "TRUE");
|
|
90
|
+
assert.equal(report.recordings.length, 1);
|
|
91
|
+
assert.equal(report.anchors.length, 2);
|
|
92
|
+
const rec = report.recordings[0]!;
|
|
93
|
+
assert.equal(rec.result, "TRUE");
|
|
94
|
+
assert.equal(rec.filePath, "random-043.txt");
|
|
95
|
+
assert.deepEqual(
|
|
96
|
+
rec.lines.map((l) => [l.name, l.result]),
|
|
97
|
+
[
|
|
98
|
+
["file", "TRUE"],
|
|
99
|
+
["signature", "TRUE"],
|
|
100
|
+
["attestation", "TRUE"],
|
|
101
|
+
["enclave", "TRUE"],
|
|
102
|
+
]
|
|
103
|
+
);
|
|
104
|
+
for (const anchor of report.anchors) {
|
|
105
|
+
assert.equal(anchor.result, "TRUE");
|
|
106
|
+
assert.deepEqual(
|
|
107
|
+
anchor.lines.map((l) => [l.name, l.result]),
|
|
108
|
+
[
|
|
109
|
+
["signature", "TRUE"],
|
|
110
|
+
["witness", "TRUE"],
|
|
111
|
+
]
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
assert.equal(report.contradictions.length, 0);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it("brackets the recording between the two verified block headers", () => {
|
|
118
|
+
const b = report.recordings[0]!.bounds;
|
|
119
|
+
assert.equal(b.status, "bracketed");
|
|
120
|
+
assert.equal(b.notBefore?.blockNumber, "25735831");
|
|
121
|
+
assert.equal(b.notAfter?.blockNumber, "25735832");
|
|
122
|
+
assert.match(b.detail, /after Ethereum block 25735831 and before block 25735832/);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("orders anchors by causal position, not file name", () => {
|
|
126
|
+
assert.deepEqual(
|
|
127
|
+
report.anchors.map((a) => a.blockNumber),
|
|
128
|
+
["25735831", "25735832"]
|
|
129
|
+
);
|
|
130
|
+
assert.equal(report.anchors[0]!.witnessPath, "ethereum-anchors/anchor-before-witness.json");
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("names the excerpt gaps as notes, never as verdicts", () => {
|
|
134
|
+
assert.ok(report.notes.some((n) => /causal positions? between the earliest and latest recording/.test(n)));
|
|
135
|
+
assert.ok(report.notes.some((n) => /link(s)? to a predecessor that is not in this bundle/.test(n)));
|
|
136
|
+
assert.equal(report.contradictions.length, 0);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("states what it cannot check", () => {
|
|
140
|
+
assert.ok(report.notChecked.some((n) => /canonical/.test(n)));
|
|
141
|
+
assert.ok(report.notChecked.some((n) => /ledger/.test(n)));
|
|
142
|
+
assert.equal(report.network, "none");
|
|
143
|
+
assert.equal(report.evaluator.version, PLAYER_VERSION);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("recognizes the enclave v5 measurement from PINS.md", () => {
|
|
147
|
+
const enclave = report.recordings[0]!.lines.find((l) => l.name === "enclave")!;
|
|
148
|
+
assert.match(enclave.detail, /enclave v5/);
|
|
149
|
+
assert.equal(KNOWN_ENCLAVE_MEASUREMENTS.length, 4);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it("serializes deterministically: no timestamps, no machine paths", async () => {
|
|
153
|
+
const again = await checkIngest(await ingestBundle(FIXTURE));
|
|
154
|
+
assert.equal(serializeCheckReport(again), serializeCheckReport(report));
|
|
155
|
+
const bytes = serializeCheckReport(report);
|
|
156
|
+
assert.ok(!bytes.includes(FIXTURE), "report must not contain the machine path");
|
|
157
|
+
assert.ok(!bytes.includes("startedAt"));
|
|
158
|
+
assert.ok(renderCheckText(report).startsWith("TRUE: this file was recorded at position 1576"));
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
describe("check: disk and memory ingest produce byte-identical reports (the no-drift guarantee)", () => {
|
|
163
|
+
it("ingestEntries over the same files equals ingestBundle over the directory", async () => {
|
|
164
|
+
const fromDisk = await checkIngest(await ingestBundle(FIXTURE));
|
|
165
|
+
const fromMemory = await checkIngest(await ingestEntries(await memoryEntriesOf(FIXTURE)));
|
|
166
|
+
assert.equal(serializeCheckReport(fromMemory), serializeCheckReport(fromDisk));
|
|
167
|
+
assert.equal(fromMemory.result, "TRUE");
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it("memory ingest tolerates any supply order (entries are sorted by path)", async () => {
|
|
171
|
+
const entries = await memoryEntriesOf(FIXTURE);
|
|
172
|
+
const reversed = [...entries].reverse();
|
|
173
|
+
const a = await checkIngest(await ingestEntries(entries));
|
|
174
|
+
const b = await checkIngest(await ingestEntries(reversed));
|
|
175
|
+
assert.equal(serializeCheckReport(a), serializeCheckReport(b));
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it("memory ingest accepts whole bytes, promises, and chunk streams alike", async () => {
|
|
179
|
+
const paths = await walk(FIXTURE);
|
|
180
|
+
const entries: BundleEntrySource[] = [];
|
|
181
|
+
for (const [i, p] of paths.entries()) {
|
|
182
|
+
const bytes = new Uint8Array(await readFile(join(FIXTURE, ...p.split("/"))));
|
|
183
|
+
const open =
|
|
184
|
+
i % 3 === 0
|
|
185
|
+
? () => bytes
|
|
186
|
+
: i % 3 === 1
|
|
187
|
+
? () => Promise.resolve(bytes)
|
|
188
|
+
: () =>
|
|
189
|
+
(async function* () {
|
|
190
|
+
const half = Math.floor(bytes.length / 2);
|
|
191
|
+
yield bytes.subarray(0, half);
|
|
192
|
+
yield bytes.subarray(half);
|
|
193
|
+
})();
|
|
194
|
+
entries.push({ path: p, open });
|
|
195
|
+
}
|
|
196
|
+
const report = await checkIngest(await ingestEntries(entries));
|
|
197
|
+
assert.equal(report.result, "TRUE");
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
describe("check: what evidence in hand contradicts, and what it merely leaves open", () => {
|
|
202
|
+
let dir: string;
|
|
203
|
+
before(async () => {
|
|
204
|
+
dir = await mkdtemp(join(tmpdir(), "bitgraph-check-"));
|
|
205
|
+
});
|
|
206
|
+
after(async () => {
|
|
207
|
+
await rm(dir, { recursive: true, force: true });
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
async function copyFixture(name: string): Promise<string> {
|
|
211
|
+
const dest = join(dir, name);
|
|
212
|
+
await cp(FIXTURE, dest, { recursive: true });
|
|
213
|
+
return dest;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
it("an edited file is UNDETERMINED (not FALSE) with a note naming it: absence is not a verdict", async () => {
|
|
217
|
+
const d = await copyFixture("edited");
|
|
218
|
+
const p = join(d, "random-043.txt");
|
|
219
|
+
await writeFile(p, Buffer.concat([await readFile(p), Buffer.from("x")]));
|
|
220
|
+
const report = await checkIngest(await ingestBundle(d));
|
|
221
|
+
assert.equal(report.result, "UNDETERMINED");
|
|
222
|
+
const file = report.recordings[0]!.lines.find((l) => l.name === "file")!;
|
|
223
|
+
assert.equal(file.result, "UNDETERMINED");
|
|
224
|
+
assert.ok(report.notes.some((n) => /random-043\.txt/.test(n) && /bytes differ/.test(n)));
|
|
225
|
+
// Everything else about the recording still holds.
|
|
226
|
+
assert.equal(report.recordings[0]!.lines.find((l) => l.name === "signature")!.result, "TRUE");
|
|
227
|
+
assert.equal(report.recordings[0]!.lines.find((l) => l.name === "attestation")!.result, "TRUE");
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it("a tampered signature is FALSE", async () => {
|
|
231
|
+
const d = await copyFixture("badsig");
|
|
232
|
+
const p = join(d, "proof.json");
|
|
233
|
+
const proof = JSON.parse(await readFile(p, "utf8")) as { signer: { signatureB64: string } };
|
|
234
|
+
const sig = Buffer.from(proof.signer.signatureB64, "base64");
|
|
235
|
+
sig[0] = sig[0]! ^ 1;
|
|
236
|
+
proof.signer.signatureB64 = sig.toString("base64");
|
|
237
|
+
await writeFile(p, JSON.stringify(proof));
|
|
238
|
+
const report = await checkIngest(await ingestBundle(d));
|
|
239
|
+
assert.equal(report.result, "FALSE");
|
|
240
|
+
assert.equal(report.recordings[0]!.lines.find((l) => l.name === "signature")!.result, "FALSE");
|
|
241
|
+
assert.match(report.summary, /^FALSE/);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it("a tampered block header is FALSE on that anchor, and the bound it gave is withdrawn", async () => {
|
|
245
|
+
const d = await copyFixture("badwitness");
|
|
246
|
+
const p = join(d, "ethereum-anchors", "anchor-after-witness.json");
|
|
247
|
+
const w = JSON.parse(await readFile(p, "utf8")) as { headerRlpHex: string };
|
|
248
|
+
const h = w.headerRlpHex;
|
|
249
|
+
w.headerRlpHex = h.slice(0, -2) + (h.slice(-2) === "00" ? "11" : "00");
|
|
250
|
+
await writeFile(p, JSON.stringify(w));
|
|
251
|
+
const report = await checkIngest(await ingestBundle(d));
|
|
252
|
+
assert.equal(report.result, "FALSE");
|
|
253
|
+
const after = report.anchors.find((a) => a.blockNumber === "25735832")!;
|
|
254
|
+
assert.equal(after.lines.find((l) => l.name === "witness")!.result, "FALSE");
|
|
255
|
+
assert.equal(report.recordings[0]!.result, "TRUE", "the recording itself is still sound");
|
|
256
|
+
assert.equal(report.recordings[0]!.bounds.status, "lower-bounded");
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it("proof plus file with no anchors is TRUE and unanchored", async () => {
|
|
260
|
+
const entries: BundleEntrySource[] = ["proof.json", "random-043.txt"].map((name) => ({
|
|
261
|
+
path: name,
|
|
262
|
+
open: () => readFile(join(FIXTURE, name)).then((b) => new Uint8Array(b)),
|
|
263
|
+
}));
|
|
264
|
+
const report = await checkIngest(await ingestEntries(entries));
|
|
265
|
+
assert.equal(report.result, "TRUE");
|
|
266
|
+
assert.equal(report.recordings[0]!.bounds.status, "unanchored");
|
|
267
|
+
assert.equal(report.anchors.length, 0);
|
|
268
|
+
assert.match(report.summary, /with no Ethereum bound in this bundle/);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it("proof alone (no file) is UNDETERMINED: signature and attestation hold, binding to bytes does not", async () => {
|
|
272
|
+
const entries: BundleEntrySource[] = [
|
|
273
|
+
{ path: "proof.json", open: () => readFile(join(FIXTURE, "proof.json")).then((b) => new Uint8Array(b)) },
|
|
274
|
+
];
|
|
275
|
+
const report = await checkIngest(await ingestEntries(entries));
|
|
276
|
+
assert.equal(report.result, "UNDETERMINED");
|
|
277
|
+
const rec = report.recordings[0]!;
|
|
278
|
+
assert.equal(rec.lines.find((l) => l.name === "file")!.result, "UNDETERMINED");
|
|
279
|
+
assert.equal(rec.lines.find((l) => l.name === "signature")!.result, "TRUE");
|
|
280
|
+
assert.equal(rec.filePath, undefined);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it("without WebCrypto the attestation is UNDETERMINED with the reason, never FALSE", async () => {
|
|
284
|
+
const report = await checkIngest(await ingestBundle(FIXTURE), { webCryptoAvailable: false });
|
|
285
|
+
const rec = report.recordings[0]!;
|
|
286
|
+
assert.equal(rec.lines.find((l) => l.name === "attestation")!.result, "UNDETERMINED");
|
|
287
|
+
assert.match(rec.lines.find((l) => l.name === "attestation")!.detail, /WebCrypto/);
|
|
288
|
+
assert.equal(rec.lines.find((l) => l.name === "enclave")!.result, "UNDETERMINED");
|
|
289
|
+
assert.equal(report.result, "UNDETERMINED");
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
it("an empty bundle is UNDETERMINED and says so", async () => {
|
|
293
|
+
const report = await checkIngest(await ingestEntries([]));
|
|
294
|
+
assert.equal(report.result, "UNDETERMINED");
|
|
295
|
+
assert.match(report.summary, /no BitGraph proofs were found/);
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
describe("check: synthetic audit shapes", () => {
|
|
300
|
+
it("an unknown PCR0 is UNDETERMINED (outside this verifier's knowledge), never FALSE", () => {
|
|
301
|
+
const audit = complete(
|
|
302
|
+
makeAudit({
|
|
303
|
+
proofs: [{ name: "a", digestB64: digestFor("a"), epochId: "E", counter: "5", slotCounter: "4" }],
|
|
304
|
+
partitions: [{ epochId: "E", members: ["a"] }],
|
|
305
|
+
})
|
|
306
|
+
);
|
|
307
|
+
audit.attestations.records.push({
|
|
308
|
+
proofHash: "proofhash-a",
|
|
309
|
+
declaredMeasurementPresent: true,
|
|
310
|
+
declaredMeasurement: "ff".repeat(48),
|
|
311
|
+
documentPresent: true,
|
|
312
|
+
attestationFormat: "aws-nitro",
|
|
313
|
+
documentValidated: true,
|
|
314
|
+
checks: [],
|
|
315
|
+
attestedPcr0: "ff".repeat(48),
|
|
316
|
+
pcr0MatchesDeclared: true,
|
|
317
|
+
userDataBoundToProof: true,
|
|
318
|
+
});
|
|
319
|
+
const report = buildCheckReport(audit);
|
|
320
|
+
const rec = report.recordings[0]!;
|
|
321
|
+
assert.equal(rec.lines.find((l) => l.name === "attestation")!.result, "TRUE");
|
|
322
|
+
const enclave = rec.lines.find((l) => l.name === "enclave")!;
|
|
323
|
+
assert.equal(enclave.result, "UNDETERMINED");
|
|
324
|
+
assert.match(enclave.detail, /not among the BitGraph enclave measurements this verifier knows/);
|
|
325
|
+
assert.equal(report.result, "UNDETERMINED");
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it("an attestation bound to some other proof is FALSE", () => {
|
|
329
|
+
const audit = complete(
|
|
330
|
+
makeAudit({
|
|
331
|
+
proofs: [{ name: "a", digestB64: digestFor("a"), epochId: "E", counter: "5" }],
|
|
332
|
+
partitions: [{ epochId: "E", members: ["a"] }],
|
|
333
|
+
})
|
|
334
|
+
);
|
|
335
|
+
audit.attestations.records.push({
|
|
336
|
+
proofHash: "proofhash-a",
|
|
337
|
+
declaredMeasurementPresent: true,
|
|
338
|
+
documentPresent: true,
|
|
339
|
+
documentValidated: true,
|
|
340
|
+
checks: [],
|
|
341
|
+
attestedPcr0: KNOWN_ENCLAVE_MEASUREMENTS[3]!.pcr0,
|
|
342
|
+
pcr0MatchesDeclared: true,
|
|
343
|
+
userDataBoundToProof: false,
|
|
344
|
+
});
|
|
345
|
+
const report = buildCheckReport(audit);
|
|
346
|
+
assert.equal(report.recordings[0]!.lines.find((l) => l.name === "attestation")!.result, "FALSE");
|
|
347
|
+
assert.equal(report.result, "FALSE");
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
it("structural contradictions surface as FALSE while excerpt gaps stay notes", () => {
|
|
351
|
+
const audit = complete(
|
|
352
|
+
makeAudit({
|
|
353
|
+
proofs: [
|
|
354
|
+
{ name: "a", digestB64: digestFor("a"), epochId: "E", counter: "5" },
|
|
355
|
+
{ name: "b", digestB64: digestFor("b"), epochId: "E", counter: "5" },
|
|
356
|
+
],
|
|
357
|
+
partitions: [{ epochId: "E", members: ["a", "b"] }],
|
|
358
|
+
})
|
|
359
|
+
);
|
|
360
|
+
audit.anomalies.anomalies.push(
|
|
361
|
+
{ code: "unexplained-counter-positions", proofHashes: [], message: "gap", details: { count: "3", ranges: [], positions: [], truncated: false } },
|
|
362
|
+
{ code: "chain-break-missing", proofHashes: ["proofhash-a"], message: "missing pred", details: {} },
|
|
363
|
+
{ code: "counter-collision", proofHashes: ["proofhash-a", "proofhash-b"], message: "two commits at position 5" }
|
|
364
|
+
);
|
|
365
|
+
const report = buildCheckReport(audit);
|
|
366
|
+
assert.equal(report.contradictions.length, 1);
|
|
367
|
+
assert.match(report.contradictions[0]!.detail, /^counter-collision/);
|
|
368
|
+
assert.ok(report.notes.some((n) => /3 causal positions/.test(n)));
|
|
369
|
+
assert.equal(report.result, "FALSE");
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
describe("check: CLI", () => {
|
|
374
|
+
it("prints the human report and exits 0 on the real fixture", () => {
|
|
375
|
+
const r = spawnSync(process.execPath, [CLI_PATH, "check", FIXTURE], { encoding: "utf8" });
|
|
376
|
+
assert.equal(r.status, 0, r.stderr);
|
|
377
|
+
assert.match(r.stdout, /^TRUE: this file was recorded at position 1576/);
|
|
378
|
+
assert.match(r.stdout, /Result: TRUE/);
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
it("--json prints the bitgraph-check/1 report", () => {
|
|
382
|
+
const r = spawnSync(process.execPath, [CLI_PATH, "check", FIXTURE, "--json"], { encoding: "utf8" });
|
|
383
|
+
assert.equal(r.status, 0, r.stderr);
|
|
384
|
+
const parsed = JSON.parse(r.stdout) as CheckReport;
|
|
385
|
+
assert.equal(parsed.check, "bitgraph-check/1");
|
|
386
|
+
assert.equal(parsed.result, "TRUE");
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
it("accepts a list of files and ingests them in memory", () => {
|
|
390
|
+
const r = spawnSync(
|
|
391
|
+
process.execPath,
|
|
392
|
+
[CLI_PATH, "check", join(FIXTURE, "proof.json"), join(FIXTURE, "random-043.txt")],
|
|
393
|
+
{ encoding: "utf8" }
|
|
394
|
+
);
|
|
395
|
+
assert.equal(r.status, 0, r.stderr);
|
|
396
|
+
assert.match(r.stdout, /no Ethereum bound in this bundle/);
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
it("exits 2 for UNDETERMINED (proof alone) and 3 for a missing path", () => {
|
|
400
|
+
const u = spawnSync(process.execPath, [CLI_PATH, "check", join(FIXTURE, "proof.json")], { encoding: "utf8" });
|
|
401
|
+
assert.equal(u.status, 2, u.stderr);
|
|
402
|
+
const e = spawnSync(process.execPath, [CLI_PATH, "check", join(FIXTURE, "does-not-exist")], { encoding: "utf8" });
|
|
403
|
+
assert.equal(e.status, 3);
|
|
404
|
+
assert.match(e.stderr, /cannot read bundle/);
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
it("evaluate and init reject --json (it belongs to check only)", () => {
|
|
408
|
+
const r = spawnSync(process.execPath, [CLI_PATH, "init", join(FIXTURE, "random-043.txt"), "--json"], { encoding: "utf8" });
|
|
409
|
+
assert.equal(r.status, 3);
|
|
410
|
+
assert.match(r.stderr, /usage:/);
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
it("the relative path helper is unused by the report (paths are bundle-relative only)", () => {
|
|
414
|
+
// Guard against a future report field leaking absolute paths.
|
|
415
|
+
assert.equal(relative(FIXTURE, join(FIXTURE, "proof.json")), "proof.json");
|
|
416
|
+
});
|
|
417
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "bitgraph-anchor-witness/1",
|
|
3
|
+
"headerRlpHex": "0xf90278a0b40e3a88ae7d5c107dd48503c73036a9ec382cf807c8ade7902389c161e93e77a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794dadb0d80178819f2319190d340ce9a924f783711a0421e753106383049bcf5c9fd339b3e40737ebfca4a41117bc26162bc2b542f7da0222fa1b22c0331e3c36cd9b7d11d5dd38e72106617f8eefcb7e1e34c58e87b64a0e1b785033a8cbc93c926e779d4a20e76b959cb4a507426258aec8223b32739d8b901007df77d335fcfbfbfffefefffbffbff7efb5bffefcdfb7ffbfff7bfffeebfefff9fffbefae4dfc3757dfffbff892fbfffffab77f7feefb9fffdfadffd16ff6febffffd2c75ffefffb5bff7f1b7dedffffc077f6fffb75dffaf1c7d2e5fff63f755f3ed120ffeefeffddfdefefbfbbfdffbe575efffdf7e5d33fff7fff2ffbf6ef83ff6bbbf7bf77fefbefe9faf737f7bfc7f5c5b7fdefffffed7bff5775f7ffeedf7777feefbf7f1e7f7fb5cfdc6bfddbff7edefefdddfd4ddfffff3bbfefe7ff7fedfd3fdfefeffffffffff9597ffe759ffff3dffffff7feddf7f7fa756f7cdacbffff77df7fdfaf2fff73f6d9df7deee5ff97b1fdfffdfefbdbfb7df79fffbf80840188b298840393870084020e1228846a7bd55b8a4275696c6465724e6574a003e75244081f38a3700ddbd87fd5c9ca45d2424c478ef199371134924a9462e588000000000000000084049120a8a0cc35135a513f4b5594eedd2ad8ee10e49ec602f209585b3c96776fb71ec9b0e7831e0000840aafde36a0cb0fbc3b6f4ec529821e2c0b3122ba994bf018f24b0286717010024229e1cc09a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
4
|
+
"blockNumber": 25735832,
|
|
5
|
+
"blockHash": "0xd20342041898e98ecaa7a07ce4d962561288755e23984e0114d154a5e75bd1a1"
|
|
6
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "bitgraph/1",
|
|
3
|
+
"artifact": {
|
|
4
|
+
"hashAlg": "sha256",
|
|
5
|
+
"digestB64": "ya3LF/xYXUsyLLaRa5atPA0w36iNe2sOEZtMFJzoCx8="
|
|
6
|
+
},
|
|
7
|
+
"commit": {
|
|
8
|
+
"nonceB64": "Z9NHxN5Vx7f3N8SRlk8Uah9RjD64Kbt9xedB83Mv3Ag=",
|
|
9
|
+
"counter": "1670",
|
|
10
|
+
"slotCounter": "1669",
|
|
11
|
+
"slotHashB64": "BcWtB3Ml8S3x9BujCeLH1b+c/VSdwyFViqeX0xDNOqg=",
|
|
12
|
+
"epochId": "kAx9jUikwWxf+alVyitZcqWPpYeRaDanlZFBVsm2q9s=",
|
|
13
|
+
"prevB64": "Khd8P6SVzr481lW63viAVAwwkXMrl5jX3uBeMjfFQZ8=",
|
|
14
|
+
"chainId": "bitgraph:main"
|
|
15
|
+
},
|
|
16
|
+
"signer": {
|
|
17
|
+
"publicKeyB64": "+EyavXXDJAvztDWhIh8Fu03WwMfUzYVgCXnp1lU18Ds=",
|
|
18
|
+
"signatureB64": "zVXdodzwzhm7fIsm7nz7CGuwHmeHAjA1gzCEN1G/QicFBZ6sprdedV2OVjHtedKZDxbQOSvVU60hSD2Dj6iaAQ=="
|
|
19
|
+
},
|
|
20
|
+
"environment": {
|
|
21
|
+
"enforcement": "measured-tee",
|
|
22
|
+
"measurement": "6483cedffed74680ffb287507744a398b288c3fb943eb3f2e4fe889f8b60b3d575ad8942350360b69a1bd7bf713df27f",
|
|
23
|
+
"attestation": {
|
|
24
|
+
"format": "aws-nitro",
|
|
25
|
+
"reportB64": "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"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"slotAllocation": {
|
|
29
|
+
"version": "bitgraph/slot/1",
|
|
30
|
+
"nonceB64": "Z9NHxN5Vx7f3N8SRlk8Uah9RjD64Kbt9xedB83Mv3Ag=",
|
|
31
|
+
"counter": "1669",
|
|
32
|
+
"epochId": "kAx9jUikwWxf+alVyitZcqWPpYeRaDanlZFBVsm2q9s=",
|
|
33
|
+
"publicKeyB64": "+EyavXXDJAvztDWhIh8Fu03WwMfUzYVgCXnp1lU18Ds=",
|
|
34
|
+
"chainId": "bitgraph:main",
|
|
35
|
+
"signatureB64": "sEx4coi4XxoaFCuUnOPDnvLa5uJfEuafAt44kmVpAQMbhJjwIXz5Hq2xeynIWgWdd91zYuHW+R/goDARTSLNAA=="
|
|
36
|
+
},
|
|
37
|
+
"attribution": {
|
|
38
|
+
"name": "Ethereum Anchor",
|
|
39
|
+
"title": "https://etherscan.io/block/25735832",
|
|
40
|
+
"message": "0xd20342041898e98ecaa7a07ce4d962561288755e23984e0114d154a5e75bd1a1"
|
|
41
|
+
},
|
|
42
|
+
"proofHash": "dWyW7MuTIAbQAHNoRyohc17A9GhGD1Cof9JqtAFUrF4="
|
|
43
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "bitgraph-anchor-witness/1",
|
|
3
|
+
"headerRlpHex": "0xf90286a02503d8262a3a5bd39a93f835f338a720434de7db353666a432d3af470ffc32e0a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347944838b106fce9647bdf1e7877bf73ce8b0bad5f97a0cf917d0242c222689c6ffec1e370ede05b474b64bf872cff3f1e77b207e84df0a0860c3a345b84903a1b2c6222e217424fd9ecc7df833db93ddd5534c82c35cb5ca0fbcccc621bc16881ca28d5be42348d32da5ec5614576be29f61f4413a6eea770b90100b9f73afff7fbdd71edef3fabfaf67dbf67f60f4bdfcf3aefeffd45fdfff8ed3f7dfe5f39b96f87b7cff6dbbf7cfe7395bf7ffefbfff3fffff7fbc7f7bbfe67c5fef6ffff4ffefbbd6e7f59bff3779eb9c7ff5f3fb2ff6c77befbff97ddefff86fcbcff55bffbfcd794f48fb3fcbeafc5faab4faf69ce77fe2bf0fbbf53ffde3b9d7776fff9feeb5bbbeff67eff17e7fff37bdab3ff8dc65fd5e76de5bbfcd53d7fef95777fd1af6fdd757bfebaf7fdce557ffff5e9be7e4b4fecbfbeb6f7ef73efafff8f67ebdf7712dbdff8057cffb53fcfffe37e69f1fa777bfbbaeb11fda6e676bd65b760bf9c5ff6d7fffefbdffdffedddff9ffb3d69b35ffa7c7ece7db780840188b29784039387008402077531846a7bd54398546974616e2028746974616e6275696c6465722e78797a29a0ec6cba377edad8dba8ff3c107a4a3df470239a0ae9d0fcdd11efddc52fb8358188000000000000000084047dc210a09f522911c579bcb780c77c3f3684c5478b64265ae99f6b11017b22d425343b3883060000840aadde36a0c3ab61e8d9a8e9935d60604b636336867145eebed5408f477aa1f239fa6a125ba0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
4
|
+
"blockNumber": 25735831,
|
|
5
|
+
"blockHash": "0xb40e3a88ae7d5c107dd48503c73036a9ec382cf807c8ade7902389c161e93e77"
|
|
6
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "bitgraph/1",
|
|
3
|
+
"artifact": {
|
|
4
|
+
"hashAlg": "sha256",
|
|
5
|
+
"digestB64": "ki5C7mF2smUeovIXfsjaQWDpJlNeuh/RqojLVO9x1po="
|
|
6
|
+
},
|
|
7
|
+
"commit": {
|
|
8
|
+
"nonceB64": "Yy8vOkAYWfg49uKe6ageYcGqTZ1XQoqIlnn3i2cU6iI=",
|
|
9
|
+
"counter": "1428",
|
|
10
|
+
"slotCounter": "1427",
|
|
11
|
+
"slotHashB64": "CDiOgdW2+WfYRYFgC3Nq7nFGORlAna5rhumMPw0jIRI=",
|
|
12
|
+
"epochId": "kAx9jUikwWxf+alVyitZcqWPpYeRaDanlZFBVsm2q9s=",
|
|
13
|
+
"prevB64": "7l8DjZkNO//ouuiDP9SqlZ4zjX0coCOgnYfOOOAnsf4=",
|
|
14
|
+
"chainId": "bitgraph:main"
|
|
15
|
+
},
|
|
16
|
+
"signer": {
|
|
17
|
+
"publicKeyB64": "+EyavXXDJAvztDWhIh8Fu03WwMfUzYVgCXnp1lU18Ds=",
|
|
18
|
+
"signatureB64": "Qkx5qkbs9ftKA5RSYFjBZiSSpwoOaIzrTL7hHfvoo8DLMfnVoh+gSlJLKQzpqI5eTZ/nF62uXel3wlzyUY/iDA=="
|
|
19
|
+
},
|
|
20
|
+
"environment": {
|
|
21
|
+
"enforcement": "measured-tee",
|
|
22
|
+
"measurement": "6483cedffed74680ffb287507744a398b288c3fb943eb3f2e4fe889f8b60b3d575ad8942350360b69a1bd7bf713df27f",
|
|
23
|
+
"attestation": {
|
|
24
|
+
"format": "aws-nitro",
|
|
25
|
+
"reportB64": "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"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"slotAllocation": {
|
|
29
|
+
"version": "bitgraph/slot/1",
|
|
30
|
+
"nonceB64": "Yy8vOkAYWfg49uKe6ageYcGqTZ1XQoqIlnn3i2cU6iI=",
|
|
31
|
+
"counter": "1427",
|
|
32
|
+
"epochId": "kAx9jUikwWxf+alVyitZcqWPpYeRaDanlZFBVsm2q9s=",
|
|
33
|
+
"publicKeyB64": "+EyavXXDJAvztDWhIh8Fu03WwMfUzYVgCXnp1lU18Ds=",
|
|
34
|
+
"chainId": "bitgraph:main",
|
|
35
|
+
"signatureB64": "3O+/iIgdF4/9YImCVjT7keEmaJ/bu63x61l7GJvBFPVrqto5S2RDQKluhEvX8HjREvnZhXrTG2FU1aL2P4msDg=="
|
|
36
|
+
},
|
|
37
|
+
"attribution": {
|
|
38
|
+
"name": "Ethereum Anchor",
|
|
39
|
+
"title": "https://etherscan.io/block/25735831",
|
|
40
|
+
"message": "0xb40e3a88ae7d5c107dd48503c73036a9ec382cf807c8ade7902389c161e93e77"
|
|
41
|
+
},
|
|
42
|
+
"proofHash": "dkZTDDfmmrAxL1FWJwqJXBUH8AxCWUr6cLT7eA79Fhw=",
|
|
43
|
+
"ethereum": {
|
|
44
|
+
"blockNumber": 25735831,
|
|
45
|
+
"blockHash": "0xb40e3a88ae7d5c107dd48503c73036a9ec382cf807c8ade7902389c161e93e77"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "bitgraph/1",
|
|
3
|
+
"artifact": {
|
|
4
|
+
"hashAlg": "sha256",
|
|
5
|
+
"digestB64": "3Kd6s+IH9E16ilJwjwVoA47aX1+/Vpug7ZvoOG/Ey0Q="
|
|
6
|
+
},
|
|
7
|
+
"commit": {
|
|
8
|
+
"nonceB64": "LYSulvQ7stSMXVL/8YmqRfbQc5MkFwY33Tv84dydsWY=",
|
|
9
|
+
"counter": "1576",
|
|
10
|
+
"slotCounter": "1575",
|
|
11
|
+
"slotHashB64": "sDGBx/qIwaWvlOATtNawHFIdtSxse06DN+dQsVb2CQA=",
|
|
12
|
+
"epochId": "kAx9jUikwWxf+alVyitZcqWPpYeRaDanlZFBVsm2q9s=",
|
|
13
|
+
"prevB64": "Uc8T79DBE1RD+dGIld3O0wiBdfXKO+ibhMEcOCtKQqc=",
|
|
14
|
+
"chainId": "bitgraph:main"
|
|
15
|
+
},
|
|
16
|
+
"signer": {
|
|
17
|
+
"publicKeyB64": "+EyavXXDJAvztDWhIh8Fu03WwMfUzYVgCXnp1lU18Ds=",
|
|
18
|
+
"signatureB64": "JV/hav0LDSLu0/2VxL31KhBb2yEB2qGmWYflXep+qAK298cuf9VsdXNB3+JKVERV9mls0yA+1nUKct3TjgoyDg=="
|
|
19
|
+
},
|
|
20
|
+
"environment": {
|
|
21
|
+
"enforcement": "measured-tee",
|
|
22
|
+
"measurement": "6483cedffed74680ffb287507744a398b288c3fb943eb3f2e4fe889f8b60b3d575ad8942350360b69a1bd7bf713df27f",
|
|
23
|
+
"attestation": {
|
|
24
|
+
"format": "aws-nitro",
|
|
25
|
+
"reportB64": "hEShATgioFkRI79pbW9kdWxlX2lkeCdpLTA2NTAyNzM0MjNmZjY3NTY3LWVuYzAxOWZmMzQzZWJhYzcyMzhmZGlnZXN0ZlNIQTM4NGl0aW1lc3RhbXAbAAABn/O5RrpkcGNyc7AAWDBkg87f/tdGgP+yh1B3RKOYsojD+5Q+s/Lk/oifi2Cz1XWtiUI1A2C2mhvXv3E98n8BWDBLTVs2YbPvwSkgkAyA4Sbkzng8Ui3mwCoqW/evOiuTJ7hndvGI5L4cHEBKEp29pJMCWDAynb/jQM5eHKp3DXM2OyH3mevEVlkkmD6tdagU/IUeRoPgtSmfqkazriLTDreBBBkDWDD+UwK5y1gm9uJGWywTP7nx46KUMZGUv4pHEWPSDdx91LwKDPm88/yRbkF8pnByVT4EWDB/NnLXYAC6yWpaRfuiml8mtOMJ0c28NmxuHHZxb2qRGqxwMMGDPYSq4Peo5aubZAIFWDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGWDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHWDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIWDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJWDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKWDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALWDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMWDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANWDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOWDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPWDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrY2VydGlmaWNhdGVZAoAwggJ8MIICAaADAgECAhABn/ND66xyOAAAAABqe7dMMAoGCCqGSM49BAMDMIGOMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEPMA0GA1UECgwGQW1hem9uMQwwCgYDVQQLDANBV1MxOTA3BgNVBAMMMGktMDY1MDI3MzQyM2ZmNjc1NjcudXMtZWFzdC0yLmF3cy5uaXRyby1lbmNsYXZlczAeFw0yNjA4MTEyMzU5MDVaFw0yNjA4MTIwMjU5MDhaMIGTMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEPMA0GA1UECgwGQW1hem9uMQwwCgYDVQQLDANBV1MxPjA8BgNVBAMMNWktMDY1MDI3MzQyM2ZmNjc1NjctZW5jMDE5ZmYzNDNlYmFjNzIzOC51cy1lYXN0LTIuYXdzMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEIYc7tN9lYLpucD5kyNj0MSoNiQztZYgR22OORzvutH9nzGC6dP54EfQFy/CaVewdCACdXnGE/5bKlbf3QHUDFORVlrpzHanVHeXFX5KGWon110UgBqLXS6XoDV3gtUgdox0wGzAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIGwDAKBggqhkjOPQQDAwNpADBmAjEAhl8xJCNOol7s1BZjJug6BUXkvrTcujHTrEjDOLpHY6icPpel0XFXnPi01grkbFwvAjEAs5DymwW8Q/s97U5AdV02gVVkPbEz7ydHId9zqb9llvMT1D8WqxnCIwcB4mk1bxHaaGNhYnVuZGxlhFkCFTCCAhEwggGWoAMCAQICEQD5MXVoG5Cv4R1GzLTk5/hWMAoGCCqGSM49BAMDMEkxCzAJBgNVBAYTAlVTMQ8wDQYDVQQKDAZBbWF6b24xDDAKBgNVBAsMA0FXUzEbMBkGA1UEAwwSYXdzLm5pdHJvLWVuY2xhdmVzMB4XDTE5MTAyODEzMjgwNVoXDTQ5MTAyODE0MjgwNVowSTELMAkGA1UEBhMCVVMxDzANBgNVBAoMBkFtYXpvbjEMMAoGA1UECwwDQVdTMRswGQYDVQQDDBJhd3Mubml0cm8tZW5jbGF2ZXMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT8AlTrpgjB82hw4prakL5GODKSc26JS//2ctmJREtQUeU0pLH22+PAvFgaMrexdgcO3hLWmj/qIRtm51LPfdHdCV9vE3D0FwhD2dwQASHkz2MBKAlmRIfJeWKEME3FP/SjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJAltQ3ZBUfnlsOW+nKdz5mp30uWMA4GA1UdDwEB/wQEAwIBhjAKBggqhkjOPQQDAwNpADBmAjEAo38vkaHJvV7nuGJ8FpjSVQOOHwND+VtjqWKMPTmAlUWhHry/LjtV2K7ucbTD1q3zAjEAovObFgWycCil3UugabUBbmW0+96P4AYdalMZf5za9dlDvGH8K+sDy2/ujSMC89/2WQLCMIICvjCCAkWgAwIBAgIRAJfoNNpEC3gE5OD0gRuLL1AwCgYIKoZIzj0EAwMwSTELMAkGA1UEBhMCVVMxDzANBgNVBAoMBkFtYXpvbjEMMAoGA1UECwwDQVdTMRswGQYDVQQDDBJhd3Mubml0cm8tZW5jbGF2ZXMwHhcNMjYwODA3MDI0ODA3WhcNMjYwODI3MDM0ODA3WjBkMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGQW1hem9uMQwwCgYDVQQLDANBV1MxNjA0BgNVBAMMLTQ1ZjU3YjJmNTI4ZmQ0Y2IudXMtZWFzdC0yLmF3cy5uaXRyby1lbmNsYXZlczB2MBAGByqGSM49AgEGBSuBBAAiA2IABLLMSvTOIr/7QWTibLSRtyva2ZCw9okkb0Ybl3hHFD/SwMNNKeS343bzpKCSS80MI5uO3n6oM0yTpKujJOHjicKMmYiPNFtLFGuKSSvKLe1kPlKfT/QdfiN3oYynBgau9KOB1TCB0jASBgNVHRMBAf8ECDAGAQH/AgECMB8GA1UdIwQYMBaAFJAltQ3ZBUfnlsOW+nKdz5mp30uWMB0GA1UdDgQWBBRZlmFoP2IvBwC31RxGlWS4TuHEdzAOBgNVHQ8BAf8EBAMCAYYwbAYDVR0fBGUwYzBhoF+gXYZbaHR0cDovL2F3cy1uaXRyby1lbmNsYXZlcy1jcmwuczMuYW1hem9uYXdzLmNvbS9jcmwvYWI0OTYwY2MtN2Q2My00MmJkLTllOWYtNTkzMzhjYjY3Zjg0LmNybDAKBggqhkjOPQQDAwNnADBkAjApHRJ8S8/LPUpjy/+7yuXiWAwdtxnGzw6vssMtsGxs6c0xcSRUsnF22WGTJ8L6IXYCMAzMhwnpVT3L7BwEi3gZDB6NkORGXMCCMgf2HtQiYHgoriPHI2HNgXwdnuQf1PjcWFkDGTCCAxUwggKaoAMCAQICEBRuHGICJn7N5PyKtslCd6IwCgYIKoZIzj0EAwMwZDELMAkGA1UEBhMCVVMxDzANBgNVBAoMBkFtYXpvbjEMMAoGA1UECwwDQVdTMTYwNAYDVQQDDC00NWY1N2IyZjUyOGZkNGNiLnVzLWVhc3QtMi5hd3Mubml0cm8tZW5jbGF2ZXMwHhcNMjYwODExMTEwNjA5WhcNMjYwODE3MDAwNjA5WjCBiTE8MDoGA1UEAwwzZWJjOTEwYTM3Mzc4ODdlNS56b25hbC51cy1lYXN0LTIuYXdzLm5pdHJvLWVuY2xhdmVzMQwwCgYDVQQLDANBV1MxDzANBgNVBAoMBkFtYXpvbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEiMM1x/0HEhamp3T1kgfG4irHIiwkjSpM1OhYNmc7hqLeAF6AUUjRSuG3k5LfL6zBORUMPdyo0nImdfeif/T+an3/66sscbLdVoBpvbIffLCt5BCvDRiJXFAAAWFJARJVo4HqMIHnMBIGA1UdEwEB/wQIMAYBAf8CAQEwHwYDVR0jBBgwFoAUWZZhaD9iLwcAt9UcRpVkuE7hxHcwHQYDVR0OBBYEFLsYdmX5qDQB2Nej/y15dzLt4loIMA4GA1UdDwEB/wQEAwIBhjCBgAYDVR0fBHkwdzB1oHOgcYZvaHR0cDovL2NybC11cy1lYXN0LTItYXdzLW5pdHJvLWVuY2xhdmVzLnMzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tL2NybC80NGZkOGIwMi00ODYwLTQ4NmItOWY4Ni0xYzk1ZjVhMmJhNjguY3JsMAoGCCqGSM49BAMDA2kAMGYCMQCjieA/CTwRsh7ci68p3uzDyy8tRmyo/jleo07SPfuVxyuxwEHomoF/XoUCzqhaYeACMQDez4f94H9j42nYD5T/fH2bM/ieYlYEnS7WYacevT70iT6iInsoT54NtatlIkhygpdZAsMwggK/MIICRaADAgECAhUAui0vaxByYVl/f5zb1xP/iqtBylEwCgYIKoZIzj0EAwMwgYkxPDA6BgNVBAMMM2ViYzkxMGEzNzM3ODg3ZTUuem9uYWwudXMtZWFzdC0yLmF3cy5uaXRyby1lbmNsYXZlczEMMAoGA1UECwwDQVdTMQ8wDQYDVQQKDAZBbWF6b24xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJXQTEQMA4GA1UEBwwHU2VhdHRsZTAeFw0yNjA4MTExNTA4MzdaFw0yNjA4MTIxNTA4MzdaMIGOMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEPMA0GA1UECgwGQW1hem9uMQwwCgYDVQQLDANBV1MxOTA3BgNVBAMMMGktMDY1MDI3MzQyM2ZmNjc1NjcudXMtZWFzdC0yLmF3cy5uaXRyby1lbmNsYXZlczB2MBAGByqGSM49AgEGBSuBBAAiA2IABDhoMFUcb8bP5C1T3N/oAjW5AkdYF14mzccQF90SDUWeC6d2tXRoMm9VXQhH0pWw8Hf3dl4HIpoujKP3dHNDBccJ8B4dKffbwUyn29CWZNg4bVXAkui5aVa27N3/6GSznKNmMGQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAgQwHQYDVR0OBBYEFI3Ez5VD2q8WGxgPpifG0Lc/M02zMB8GA1UdIwQYMBaAFLsYdmX5qDQB2Nej/y15dzLt4loIMAoGCCqGSM49BAMDA2gAMGUCMQDdHPeiFt+r7qa8mcDiSGiAeytnfNgQGJmqfJyx/sfsIb3cp4xt4KeUUNdNT6zboDwCMF0/hywl/8pBUzLamPMrSz8vEBKu66YQzdQbx+szhWczIhWAwgwoOwQP25I438SxbGpwdWJsaWNfa2V59ml1c2VyX2RhdGFYINAVQJLs+kL/79SjHamXGmdEeCGbEjLdisThDR7VOix0ZW5vbmNl9v9YYJtr3lPOL3R5mHAXe3gGszfTa5YOFTnnje+U+pX9IPF6JFs3R7orGXfRz09yaYQG/qgyolgZTp0qmymsoqB/pW6CgtfgIVAogtY9pqyIMV4XnWlC3lMEioS7LE6L03i1NA=="
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"slotAllocation": {
|
|
29
|
+
"version": "bitgraph/slot/1",
|
|
30
|
+
"nonceB64": "LYSulvQ7stSMXVL/8YmqRfbQc5MkFwY33Tv84dydsWY=",
|
|
31
|
+
"counter": "1575",
|
|
32
|
+
"epochId": "kAx9jUikwWxf+alVyitZcqWPpYeRaDanlZFBVsm2q9s=",
|
|
33
|
+
"publicKeyB64": "+EyavXXDJAvztDWhIh8Fu03WwMfUzYVgCXnp1lU18Ds=",
|
|
34
|
+
"chainId": "bitgraph:main",
|
|
35
|
+
"signatureB64": "hytURJY8GkZg9kpTF/h6k2j5VzSPTIoIHzxekfnHnHfKBrXKwhEJIVre1nkTB8nvpMHrGBwzpe52uIBSJeluBA=="
|
|
36
|
+
},
|
|
37
|
+
"proofHash": "0BVAkuz6Qv/v1KMdqZcaZ0R4IZsSMt2KxOENHtU6LHQ="
|
|
38
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
m7qLg6+ABRfTfEY3Qbs6dItlL8KOhxQbOnJnI/Gnu0/N6m6s77viLZUm8Cqzv1AgHKvnvaRhGUQ9bHCENgfPga6W0XRneVW81m1ct7Fn0LrFS+av1IzJGvqrHoI/w8uGq/xE+88lSItpzQDK8sGj3YABsDiWGwbu8m3rQCnqVoYPvKYJZ4DqbEDrHZ3wMBiCGrHqBfmb6Vl8RAHoIg4OojqTo1r95FEjiXhABYaF93X4/HRXRKUGHnzSTu2wcufSTDhzMa27FJs5H2aam5X31KkSrgxB/VrpN+eYyBfXIuNPq3eOWWFKMkAnwWL/YD0Zs0fM7mH3gaWs/Ubj//+4dPOsfknIuhN8b2A/5AZlsmHW5G25n1H+dxssHdcRoS0mPQGkjJXvDH+PIDKbpbHDo4qFGNujyBhW2SafDepwJ+nWa0edpj8TEgk53zwMLn1YIJ1RoLh7t24UORo1irqkqVegwz3OBStBqPmQ24kLrxWqdFK5qkaxe2o5HWKg+71emF8upp4Kc84nGYHhjUjo/clhAti6slHffoEjMhicpc0nw7+B1GOG1VsIsPmLMVJQclxV135uHtn1Y9y0BujjRrV4+qYL25s3hhn73wdvdnSq7vFbj8AOGrt37fyfTCs43dPXvyGDgB2M8GqbKx0m5iHqcFQEqXon1X1fLXCiubc=
|