@mikeargento/bitgraph 1.9.1 → 1.10.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.
Files changed (248) hide show
  1. package/README.md +21 -21
  2. package/dist/fuse-cli.js +2 -2
  3. package/dist/fuse-cli.js.map +1 -1
  4. package/dist/fuse.d.ts +15 -1
  5. package/dist/fuse.d.ts.map +1 -1
  6. package/dist/fuse.js +29 -12
  7. package/dist/fuse.js.map +1 -1
  8. package/package.json +12 -8
  9. package/src/fuse-cli.ts +2 -2
  10. package/src/fuse.ts +46 -13
  11. package/dist/__tests__/audit-anchors.test.d.ts +0 -2
  12. package/dist/__tests__/audit-anchors.test.d.ts.map +0 -1
  13. package/dist/__tests__/audit-anchors.test.js +0 -152
  14. package/dist/__tests__/audit-anchors.test.js.map +0 -1
  15. package/dist/__tests__/audit-anomalies.test.d.ts +0 -2
  16. package/dist/__tests__/audit-anomalies.test.d.ts.map +0 -1
  17. package/dist/__tests__/audit-anomalies.test.js +0 -663
  18. package/dist/__tests__/audit-anomalies.test.js.map +0 -1
  19. package/dist/__tests__/audit-attestation.test.d.ts +0 -2
  20. package/dist/__tests__/audit-attestation.test.d.ts.map +0 -1
  21. package/dist/__tests__/audit-attestation.test.js +0 -403
  22. package/dist/__tests__/audit-attestation.test.js.map +0 -1
  23. package/dist/__tests__/audit-bench-smoke.test.d.ts +0 -2
  24. package/dist/__tests__/audit-bench-smoke.test.d.ts.map +0 -1
  25. package/dist/__tests__/audit-bench-smoke.test.js +0 -87
  26. package/dist/__tests__/audit-bench-smoke.test.js.map +0 -1
  27. package/dist/__tests__/audit-boundary.test.d.ts +0 -20
  28. package/dist/__tests__/audit-boundary.test.d.ts.map +0 -1
  29. package/dist/__tests__/audit-boundary.test.js +0 -84
  30. package/dist/__tests__/audit-boundary.test.js.map +0 -1
  31. package/dist/__tests__/audit-cli.test.d.ts +0 -2
  32. package/dist/__tests__/audit-cli.test.d.ts.map +0 -1
  33. package/dist/__tests__/audit-cli.test.js +0 -239
  34. package/dist/__tests__/audit-cli.test.js.map +0 -1
  35. package/dist/__tests__/audit-dependencies.test.d.ts +0 -2
  36. package/dist/__tests__/audit-dependencies.test.d.ts.map +0 -1
  37. package/dist/__tests__/audit-dependencies.test.js +0 -116
  38. package/dist/__tests__/audit-dependencies.test.js.map +0 -1
  39. package/dist/__tests__/audit-fixtures.d.ts +0 -265
  40. package/dist/__tests__/audit-fixtures.d.ts.map +0 -1
  41. package/dist/__tests__/audit-fixtures.js +0 -511
  42. package/dist/__tests__/audit-fixtures.js.map +0 -1
  43. package/dist/__tests__/audit-ingest.test.d.ts +0 -2
  44. package/dist/__tests__/audit-ingest.test.d.ts.map +0 -1
  45. package/dist/__tests__/audit-ingest.test.js +0 -473
  46. package/dist/__tests__/audit-ingest.test.js.map +0 -1
  47. package/dist/__tests__/audit-memory-ingest.test.d.ts +0 -12
  48. package/dist/__tests__/audit-memory-ingest.test.d.ts.map +0 -1
  49. package/dist/__tests__/audit-memory-ingest.test.js +0 -135
  50. package/dist/__tests__/audit-memory-ingest.test.js.map +0 -1
  51. package/dist/__tests__/audit-property.test.d.ts +0 -2
  52. package/dist/__tests__/audit-property.test.d.ts.map +0 -1
  53. package/dist/__tests__/audit-property.test.js +0 -771
  54. package/dist/__tests__/audit-property.test.js.map +0 -1
  55. package/dist/__tests__/audit-real-fixtures.test.d.ts +0 -2
  56. package/dist/__tests__/audit-real-fixtures.test.d.ts.map +0 -1
  57. package/dist/__tests__/audit-real-fixtures.test.js +0 -132
  58. package/dist/__tests__/audit-real-fixtures.test.js.map +0 -1
  59. package/dist/__tests__/audit-real-live.test.d.ts +0 -2
  60. package/dist/__tests__/audit-real-live.test.d.ts.map +0 -1
  61. package/dist/__tests__/audit-real-live.test.js +0 -107
  62. package/dist/__tests__/audit-real-live.test.js.map +0 -1
  63. package/dist/__tests__/audit-reconstruct.test.d.ts +0 -2
  64. package/dist/__tests__/audit-reconstruct.test.d.ts.map +0 -1
  65. package/dist/__tests__/audit-reconstruct.test.js +0 -287
  66. package/dist/__tests__/audit-reconstruct.test.js.map +0 -1
  67. package/dist/__tests__/audit-report.test.d.ts +0 -2
  68. package/dist/__tests__/audit-report.test.d.ts.map +0 -1
  69. package/dist/__tests__/audit-report.test.js +0 -186
  70. package/dist/__tests__/audit-report.test.js.map +0 -1
  71. package/dist/__tests__/audit-roundtrip.test.d.ts +0 -2
  72. package/dist/__tests__/audit-roundtrip.test.d.ts.map +0 -1
  73. package/dist/__tests__/audit-roundtrip.test.js +0 -368
  74. package/dist/__tests__/audit-roundtrip.test.js.map +0 -1
  75. package/dist/__tests__/audit-temporal.test.d.ts +0 -2
  76. package/dist/__tests__/audit-temporal.test.d.ts.map +0 -1
  77. package/dist/__tests__/audit-temporal.test.js +0 -364
  78. package/dist/__tests__/audit-temporal.test.js.map +0 -1
  79. package/dist/__tests__/audit-tiers.test.d.ts +0 -2
  80. package/dist/__tests__/audit-tiers.test.d.ts.map +0 -1
  81. package/dist/__tests__/audit-tiers.test.js +0 -282
  82. package/dist/__tests__/audit-tiers.test.js.map +0 -1
  83. package/dist/__tests__/audit-witness-real.test.d.ts +0 -19
  84. package/dist/__tests__/audit-witness-real.test.d.ts.map +0 -1
  85. package/dist/__tests__/audit-witness-real.test.js +0 -82
  86. package/dist/__tests__/audit-witness-real.test.js.map +0 -1
  87. package/dist/__tests__/audit-witness.test.d.ts +0 -2
  88. package/dist/__tests__/audit-witness.test.d.ts.map +0 -1
  89. package/dist/__tests__/audit-witness.test.js +0 -308
  90. package/dist/__tests__/audit-witness.test.js.map +0 -1
  91. package/dist/__tests__/canonical.test.d.ts +0 -2
  92. package/dist/__tests__/canonical.test.d.ts.map +0 -1
  93. package/dist/__tests__/canonical.test.js +0 -162
  94. package/dist/__tests__/canonical.test.js.map +0 -1
  95. package/dist/__tests__/chain-hash-anchor.test.d.ts +0 -22
  96. package/dist/__tests__/chain-hash-anchor.test.d.ts.map +0 -1
  97. package/dist/__tests__/chain-hash-anchor.test.js +0 -55
  98. package/dist/__tests__/chain-hash-anchor.test.js.map +0 -1
  99. package/dist/__tests__/commit-service.integration.test.d.ts +0 -2
  100. package/dist/__tests__/commit-service.integration.test.d.ts.map +0 -1
  101. package/dist/__tests__/commit-service.integration.test.js +0 -95
  102. package/dist/__tests__/commit-service.integration.test.js.map +0 -1
  103. package/dist/__tests__/constructor.test.d.ts +0 -2
  104. package/dist/__tests__/constructor.test.d.ts.map +0 -1
  105. package/dist/__tests__/constructor.test.js +0 -267
  106. package/dist/__tests__/constructor.test.js.map +0 -1
  107. package/dist/__tests__/declared-proof-fixture.d.ts +0 -66
  108. package/dist/__tests__/declared-proof-fixture.d.ts.map +0 -1
  109. package/dist/__tests__/declared-proof-fixture.js +0 -66
  110. package/dist/__tests__/declared-proof-fixture.js.map +0 -1
  111. package/dist/__tests__/fuse-inline.test.d.ts +0 -2
  112. package/dist/__tests__/fuse-inline.test.d.ts.map +0 -1
  113. package/dist/__tests__/fuse-inline.test.js +0 -181
  114. package/dist/__tests__/fuse-inline.test.js.map +0 -1
  115. package/dist/__tests__/fuse-placement.test.d.ts +0 -2
  116. package/dist/__tests__/fuse-placement.test.d.ts.map +0 -1
  117. package/dist/__tests__/fuse-placement.test.js +0 -31
  118. package/dist/__tests__/fuse-placement.test.js.map +0 -1
  119. package/dist/__tests__/fuse-roundtrip.test.d.ts +0 -2
  120. package/dist/__tests__/fuse-roundtrip.test.d.ts.map +0 -1
  121. package/dist/__tests__/fuse-roundtrip.test.js +0 -241
  122. package/dist/__tests__/fuse-roundtrip.test.js.map +0 -1
  123. package/dist/__tests__/fuse-sdk.test.d.ts +0 -2
  124. package/dist/__tests__/fuse-sdk.test.d.ts.map +0 -1
  125. package/dist/__tests__/fuse-sdk.test.js +0 -117
  126. package/dist/__tests__/fuse-sdk.test.js.map +0 -1
  127. package/dist/__tests__/fuse-set-sdk.test.d.ts +0 -2
  128. package/dist/__tests__/fuse-set-sdk.test.d.ts.map +0 -1
  129. package/dist/__tests__/fuse-set-sdk.test.js +0 -721
  130. package/dist/__tests__/fuse-set-sdk.test.js.map +0 -1
  131. package/dist/__tests__/fuse-set.test.d.ts +0 -2
  132. package/dist/__tests__/fuse-set.test.d.ts.map +0 -1
  133. package/dist/__tests__/fuse-set.test.js +0 -889
  134. package/dist/__tests__/fuse-set.test.js.map +0 -1
  135. package/dist/__tests__/fuse-set2.test.d.ts +0 -2
  136. package/dist/__tests__/fuse-set2.test.d.ts.map +0 -1
  137. package/dist/__tests__/fuse-set2.test.js +0 -294
  138. package/dist/__tests__/fuse-set2.test.js.map +0 -1
  139. package/dist/__tests__/fuse-vectors.test.d.ts +0 -2
  140. package/dist/__tests__/fuse-vectors.test.d.ts.map +0 -1
  141. package/dist/__tests__/fuse-vectors.test.js +0 -175
  142. package/dist/__tests__/fuse-vectors.test.js.map +0 -1
  143. package/dist/__tests__/fuse-verify.test.d.ts +0 -2
  144. package/dist/__tests__/fuse-verify.test.d.ts.map +0 -1
  145. package/dist/__tests__/fuse-verify.test.js +0 -250
  146. package/dist/__tests__/fuse-verify.test.js.map +0 -1
  147. package/dist/__tests__/hello-world.test.d.ts +0 -2
  148. package/dist/__tests__/hello-world.test.d.ts.map +0 -1
  149. package/dist/__tests__/hello-world.test.js +0 -9
  150. package/dist/__tests__/hello-world.test.js.map +0 -1
  151. package/dist/__tests__/mock-proof-fixture.d.ts +0 -15
  152. package/dist/__tests__/mock-proof-fixture.d.ts.map +0 -1
  153. package/dist/__tests__/mock-proof-fixture.js +0 -34
  154. package/dist/__tests__/mock-proof-fixture.js.map +0 -1
  155. package/dist/__tests__/policy-enforcement.test.d.ts +0 -2
  156. package/dist/__tests__/policy-enforcement.test.d.ts.map +0 -1
  157. package/dist/__tests__/policy-enforcement.test.js +0 -188
  158. package/dist/__tests__/policy-enforcement.test.js.map +0 -1
  159. package/dist/__tests__/proof-hash-regression.test.d.ts +0 -2
  160. package/dist/__tests__/proof-hash-regression.test.d.ts.map +0 -1
  161. package/dist/__tests__/proof-hash-regression.test.js +0 -95
  162. package/dist/__tests__/proof-hash-regression.test.js.map +0 -1
  163. package/dist/__tests__/proof-hash.test.d.ts +0 -2
  164. package/dist/__tests__/proof-hash.test.d.ts.map +0 -1
  165. package/dist/__tests__/proof-hash.test.js +0 -116
  166. package/dist/__tests__/proof-hash.test.js.map +0 -1
  167. package/dist/__tests__/proof-integrity.test.d.ts +0 -2
  168. package/dist/__tests__/proof-integrity.test.d.ts.map +0 -1
  169. package/dist/__tests__/proof-integrity.test.js +0 -454
  170. package/dist/__tests__/proof-integrity.test.js.map +0 -1
  171. package/dist/__tests__/realistic-proof-fixture.d.ts +0 -56
  172. package/dist/__tests__/realistic-proof-fixture.d.ts.map +0 -1
  173. package/dist/__tests__/realistic-proof-fixture.js +0 -57
  174. package/dist/__tests__/realistic-proof-fixture.js.map +0 -1
  175. package/dist/__tests__/run.test.d.ts +0 -2
  176. package/dist/__tests__/run.test.d.ts.map +0 -1
  177. package/dist/__tests__/run.test.js +0 -178
  178. package/dist/__tests__/run.test.js.map +0 -1
  179. package/dist/__tests__/verifier.test.d.ts +0 -2
  180. package/dist/__tests__/verifier.test.d.ts.map +0 -1
  181. package/dist/__tests__/verifier.test.js +0 -531
  182. package/dist/__tests__/verifier.test.js.map +0 -1
  183. package/dist/canonical.d.ts +0 -54
  184. package/dist/canonical.d.ts.map +0 -1
  185. package/dist/canonical.js +0 -119
  186. package/dist/canonical.js.map +0 -1
  187. package/dist/proof-hash.d.ts +0 -9
  188. package/dist/proof-hash.d.ts.map +0 -1
  189. package/dist/proof-hash.js +0 -75
  190. package/dist/proof-hash.js.map +0 -1
  191. package/dist/types.d.ts +0 -705
  192. package/dist/types.d.ts.map +0 -1
  193. package/dist/types.js +0 -3
  194. package/dist/types.js.map +0 -1
  195. package/dist/verifier.d.ts +0 -27
  196. package/dist/verifier.d.ts.map +0 -1
  197. package/dist/verifier.js +0 -844
  198. package/dist/verifier.js.map +0 -1
  199. package/src/__tests__/audit-anchors.test.ts +0 -188
  200. package/src/__tests__/audit-anomalies.test.ts +0 -815
  201. package/src/__tests__/audit-attestation.test.ts +0 -529
  202. package/src/__tests__/audit-bench-smoke.test.ts +0 -108
  203. package/src/__tests__/audit-boundary.test.ts +0 -96
  204. package/src/__tests__/audit-cli.test.ts +0 -288
  205. package/src/__tests__/audit-dependencies.test.ts +0 -141
  206. package/src/__tests__/audit-fixtures.ts +0 -736
  207. package/src/__tests__/audit-ingest.test.ts +0 -575
  208. package/src/__tests__/audit-memory-ingest.test.ts +0 -156
  209. package/src/__tests__/audit-property.test.ts +0 -892
  210. package/src/__tests__/audit-real-fixtures.test.ts +0 -153
  211. package/src/__tests__/audit-real-live.test.ts +0 -128
  212. package/src/__tests__/audit-reconstruct.test.ts +0 -353
  213. package/src/__tests__/audit-report.test.ts +0 -222
  214. package/src/__tests__/audit-roundtrip.test.ts +0 -464
  215. package/src/__tests__/audit-temporal.test.ts +0 -446
  216. package/src/__tests__/audit-tiers.test.ts +0 -343
  217. package/src/__tests__/audit-witness-real.test.ts +0 -92
  218. package/src/__tests__/audit-witness.test.ts +0 -345
  219. package/src/__tests__/canonical.test.ts +0 -253
  220. package/src/__tests__/chain-hash-anchor.test.ts +0 -67
  221. package/src/__tests__/commit-service.integration.test.ts +0 -117
  222. package/src/__tests__/constructor.test.ts +0 -340
  223. package/src/__tests__/declared-proof-fixture.ts +0 -65
  224. package/src/__tests__/fuse-inline.test.ts +0 -211
  225. package/src/__tests__/fuse-placement.test.ts +0 -32
  226. package/src/__tests__/fuse-roundtrip.test.ts +0 -243
  227. package/src/__tests__/fuse-sdk.test.ts +0 -142
  228. package/src/__tests__/fuse-set-sdk.test.ts +0 -852
  229. package/src/__tests__/fuse-set.test.ts +0 -1027
  230. package/src/__tests__/fuse-set2.test.ts +0 -343
  231. package/src/__tests__/fuse-vectors.test.ts +0 -218
  232. package/src/__tests__/fuse-verify.test.ts +0 -278
  233. package/src/__tests__/hello-world.test.ts +0 -10
  234. package/src/__tests__/mock-proof-fixture.ts +0 -36
  235. package/src/__tests__/policy-enforcement.test.ts +0 -226
  236. package/src/__tests__/proof-hash-regression.test.ts +0 -107
  237. package/src/__tests__/proof-hash.test.ts +0 -129
  238. package/src/__tests__/proof-integrity.test.ts +0 -576
  239. package/src/__tests__/real-fixtures/anchor-after-112762.json +0 -47
  240. package/src/__tests__/real-fixtures/anchor-with-ethereum-112758.json +0 -47
  241. package/src/__tests__/real-fixtures/live-proof-0.json +0 -42
  242. package/src/__tests__/real-fixtures/live-proof-1.json +0 -43
  243. package/src/__tests__/real-fixtures/live-proof-2.json +0 -43
  244. package/src/__tests__/real-fixtures/successor-112760.json +0 -38
  245. package/src/__tests__/real-fixtures/witness-25525146.json +0 -6
  246. package/src/__tests__/real-fixtures/witness-25525147.json +0 -6
  247. package/src/__tests__/realistic-proof-fixture.ts +0 -57
  248. package/src/__tests__/verifier.test.ts +0 -624
@@ -1,736 +0,0 @@
1
- // Copyright (c) Argento Computing Inc. All rights reserved. See LICENSE.
2
-
3
- /**
4
- * Shared fixture helpers for the bitgraph-audit test suites.
5
- *
6
- * Proofs that must be verifier-valid are built either through the root
7
- * Constructor (real commit path) or by manually signing the exact
8
- * canonical SignedBody layout with real Ed25519 keys, the same approach
9
- * as src/__tests__/proof-integrity.test.ts. Verifier semantics are never
10
- * bypassed.
11
- *
12
- * Also provides a minimal in-memory tar writer (ustar, PAX path records,
13
- * GNU long-name entries) so container tests never shell out.
14
- */
15
-
16
- import { mkdir, mkdtemp, writeFile } from "node:fs/promises";
17
- import { tmpdir } from "node:os";
18
- import { dirname, join } from "node:path";
19
- import { getPublicKeyAsync, signAsync } from "@noble/ed25519";
20
- import { sha256 } from "@noble/hashes/sha256";
21
- import { keccak_256 } from "@noble/hashes/sha3";
22
- import { canonicalize, computeProofHash, computeChainHash } from "@mikeargento/bitgraph-verify";
23
- import type { BitGraphProof } from "@mikeargento/bitgraph-verify";
24
- import { Constructor } from "../constructor.js";
25
- import type { HostCapabilities } from "../host.js";
26
-
27
- // ---------------------------------------------------------------------------
28
- // Encoding helpers
29
- // ---------------------------------------------------------------------------
30
-
31
- export function b64(bytes: Uint8Array): string {
32
- return Buffer.from(bytes).toString("base64");
33
- }
34
-
35
- export function utf8(text: string): Uint8Array {
36
- return new TextEncoder().encode(text);
37
- }
38
-
39
- // ---------------------------------------------------------------------------
40
- // Proof fixtures
41
- // ---------------------------------------------------------------------------
42
-
43
- /**
44
- * Source of random bytes for fixture generation. Defaults everywhere to
45
- * crypto.getRandomValues; property-based suites pass a seeded deterministic
46
- * source so the same seed always regenerates byte-identical fixtures.
47
- */
48
- export type RandomSource = (byteLength: number) => Uint8Array;
49
-
50
- const defaultRandom: RandomSource = (n) => crypto.getRandomValues(new Uint8Array(n));
51
-
52
- export interface ManualKey {
53
- privateKey: Uint8Array;
54
- publicKeyB64: string;
55
- }
56
-
57
- export async function makeKey(random?: RandomSource): Promise<ManualKey> {
58
- const privateKey = (random ?? defaultRandom)(32);
59
- const publicKeyB64 = b64(await getPublicKeyAsync(privateKey));
60
- return { privateKey, publicKeyB64 };
61
- }
62
-
63
- /**
64
- * Manually build and sign a proof over the exact canonical SignedBody the
65
- * verifier reconstructs. The commit object may carry extra fields (for
66
- * example the live enclave's undeclared chainId); because it is part of
67
- * the signed body, the signature covers them.
68
- *
69
- * Optional extras follow the canonical SignedBody rules: attribution is
70
- * included in the signed body when provided; attestationFormat is
71
- * included when an attestation is provided (the reportB64 itself stays
72
- * OUTSIDE the signed body, exactly like the enclave output, so the
73
- * report can be attached or swapped after signing without changing the
74
- * canonical hash).
75
- */
76
- export async function signBody(
77
- key: ManualKey,
78
- artifact: BitGraphProof["artifact"],
79
- commit: BitGraphProof["commit"],
80
- measurement: string,
81
- extras?: {
82
- attribution?: { name?: string; title?: string; message?: string };
83
- attestation?: { format: string; reportB64: string };
84
- }
85
- ): Promise<BitGraphProof> {
86
- const signedBody: Record<string, unknown> = {
87
- version: "bitgraph/1" as const,
88
- artifact,
89
- commit,
90
- publicKeyB64: key.publicKeyB64,
91
- enforcement: "stub" as const,
92
- measurement,
93
- };
94
- if (extras?.attribution !== undefined) signedBody["attribution"] = extras.attribution;
95
- if (extras?.attestation !== undefined) signedBody["attestationFormat"] = extras.attestation.format;
96
- const signatureB64 = b64(await signAsync(canonicalize(signedBody), key.privateKey));
97
- const proof: BitGraphProof = {
98
- version: "bitgraph/1",
99
- artifact,
100
- commit,
101
- signer: { publicKeyB64: key.publicKeyB64, signatureB64 },
102
- environment: {
103
- enforcement: "stub",
104
- measurement,
105
- ...(extras?.attestation !== undefined
106
- ? { attestation: { format: extras.attestation.format, reportB64: extras.attestation.reportB64 } }
107
- : {}),
108
- },
109
- };
110
- if (extras?.attribution !== undefined) {
111
- (proof as unknown as Record<string, unknown>)["attribution"] = extras.attribution;
112
- }
113
- return proof;
114
- }
115
-
116
- /**
117
- * Build a proof through the root Constructor (the real commit path).
118
- * Default fixtures are chainless: no counter, no epochId.
119
- */
120
- export async function makeConstructorProof(opts?: {
121
- withCounter?: boolean;
122
- epochId?: string;
123
- payload?: string;
124
- }): Promise<{ proof: BitGraphProof; bytes: Uint8Array }> {
125
- const privateKey = crypto.getRandomValues(new Uint8Array(32));
126
- const publicKeyBytes = await getPublicKeyAsync(privateKey);
127
- const measurement = "test-measurement-audit";
128
-
129
- let counter = 0;
130
- const base = {
131
- enforcementTier: "stub" as const,
132
- getMeasurement: async () => measurement,
133
- getFreshNonce: async () => crypto.getRandomValues(new Uint8Array(16)),
134
- sign: async (data: Uint8Array) => signAsync(data, privateKey),
135
- getPublicKey: async () => publicKeyBytes,
136
- };
137
- const host: HostCapabilities = opts?.withCounter
138
- ? { ...base, nextCounter: async () => String(++counter) }
139
- : base;
140
-
141
- const ctor = await Constructor.initialize(
142
- opts?.epochId !== undefined ? { host, epochId: opts.epochId } : { host }
143
- );
144
- const bytes = utf8(opts?.payload ?? "bitgraph-audit-test-payload");
145
- const proof = await ctor.commit({ bytes });
146
- return { proof, bytes };
147
- }
148
-
149
- /**
150
- * Build a verifier-valid proof carrying a chainId inside the signed
151
- * commit body, matching what the live enclave injects for non-default
152
- * chains.
153
- */
154
- export async function makeChainIdProof(opts?: {
155
- chainId?: string;
156
- counter?: string;
157
- epochId?: string;
158
- payload?: string;
159
- }): Promise<{ proof: BitGraphProof; bytes: Uint8Array }> {
160
- const key = await makeKey();
161
- const bytes = utf8(opts?.payload ?? "bitgraph-audit-chainid-payload");
162
- const commit: BitGraphProof["commit"] = {
163
- nonceB64: b64(crypto.getRandomValues(new Uint8Array(16))),
164
- ...(opts?.counter !== undefined ? { counter: opts.counter } : {}),
165
- ...(opts?.epochId !== undefined ? { epochId: opts.epochId } : {}),
166
- };
167
- (commit as unknown as Record<string, unknown>)["chainId"] = opts?.chainId ?? "bitgraph:main";
168
- const proof = await signBody(
169
- key,
170
- { hashAlg: "sha256", digestB64: b64(sha256(bytes)) },
171
- commit,
172
- "test-measurement-chainid"
173
- );
174
- return { proof, bytes };
175
- }
176
-
177
- /**
178
- * Build a verifier-valid epoch-genesis proof carrying an epochLink that
179
- * consumes the given predecessor into the given successor epoch.
180
- *
181
- * By default the predecessor key is a fresh random key; pass
182
- * prevPublicKeyB64 to reference the actual signer of an observed
183
- * predecessor. Optional counter, slotCounter, prevB64, and chainId land
184
- * in the signed commit body, matching real enclave output shapes.
185
- */
186
- export async function makeEpochLinkProof(opts: {
187
- prevEpochId: string;
188
- prevCounter: string;
189
- prevProofHashB64: string;
190
- toEpochId: string;
191
- prevPublicKeyB64?: string;
192
- key?: ManualKey;
193
- counter?: string;
194
- slotCounter?: string;
195
- prevB64?: string;
196
- chainId?: string;
197
- measurement?: string;
198
- payload?: string;
199
- random?: RandomSource;
200
- }): Promise<{ proof: BitGraphProof; bytes: Uint8Array; proofHash: string; chainHash: string; key: ManualKey }> {
201
- const random = opts.random ?? defaultRandom;
202
- const key = opts.key ?? (await makeKey(random));
203
- const prevPublicKeyB64 = opts.prevPublicKeyB64 ?? (await makeKey(random)).publicKeyB64;
204
- const bytes = utf8(opts.payload ?? `bitgraph-audit-epochlink-${opts.toEpochId}`);
205
- const commit: BitGraphProof["commit"] = {
206
- nonceB64: b64(random(16)),
207
- ...(opts.counter !== undefined ? { counter: opts.counter } : {}),
208
- ...(opts.slotCounter !== undefined ? { slotCounter: opts.slotCounter } : {}),
209
- ...(opts.prevB64 !== undefined ? { prevB64: opts.prevB64 } : {}),
210
- epochId: opts.toEpochId,
211
- epochLink: {
212
- prevEpochId: opts.prevEpochId,
213
- prevPublicKeyB64,
214
- prevCounter: opts.prevCounter,
215
- prevProofHashB64: opts.prevProofHashB64,
216
- toEpochId: opts.toEpochId,
217
- toPublicKeyB64: key.publicKeyB64,
218
- },
219
- };
220
- if (opts.chainId !== undefined) {
221
- (commit as unknown as Record<string, unknown>)["chainId"] = opts.chainId;
222
- }
223
- const proof = await signBody(
224
- key,
225
- { hashAlg: "sha256", digestB64: b64(sha256(bytes)) },
226
- commit,
227
- opts.measurement ?? "test-measurement-epochlink"
228
- );
229
- return { proof, bytes, proofHash: computeProofHash(proof), chainHash: computeChainHash(proof), key };
230
- }
231
-
232
- // ---------------------------------------------------------------------------
233
- // Linked slot/commit counter chains (real enclave shape)
234
- // ---------------------------------------------------------------------------
235
-
236
- export interface CounterChainLink {
237
- proof: BitGraphProof;
238
- bytes: Uint8Array;
239
- /** Signed-body identity hash (computeProofHash). */
240
- proofHash: string;
241
- /** Whole-proof chain hash (computeChainHash): the value a successor's prevB64 references. */
242
- chainHash: string;
243
- }
244
-
245
- /**
246
- * Build a linked chain of verifier-valid proofs under one signer key,
247
- * epoch, and chain, with explicit counter positions per proof. Each
248
- * non-first proof carries prevB64 equal to the canonical proof hash of
249
- * its predecessor; the first proof omits prevB64 entirely (genesis per
250
- * G1) unless prevB64OfFirst continues the chain from an existing proof.
251
- * Pass pairs like real enclave output (slot 1/commit 2, slot 3/
252
- * commit 4, ...) or leave positions out for counterless link chains.
253
- */
254
- export async function makeCounterChain(opts: {
255
- epochId: string;
256
- pairs: Array<{ slot?: string; commit?: string }>;
257
- key?: ManualKey;
258
- chainId?: string;
259
- measurement?: string;
260
- payloadPrefix?: string;
261
- /** Continue an existing chain: the first proof carries this prevB64 instead of being a genesis. */
262
- prevB64OfFirst?: string;
263
- random?: RandomSource;
264
- }): Promise<{ key: ManualKey; proofs: CounterChainLink[] }> {
265
- const random = opts.random ?? defaultRandom;
266
- const key = opts.key ?? (await makeKey(random));
267
- const measurement = opts.measurement ?? "test-measurement-chain";
268
- const proofs: CounterChainLink[] = [];
269
-
270
- for (let i = 0; i < opts.pairs.length; i++) {
271
- const pair = opts.pairs[i]!;
272
- const bytes = utf8(`${opts.payloadPrefix ?? opts.epochId}-payload-${i}`);
273
- const prevB64 = i > 0 ? proofs[i - 1]!.chainHash : opts.prevB64OfFirst;
274
- const commit: BitGraphProof["commit"] = {
275
- nonceB64: b64(random(16)),
276
- ...(pair.commit !== undefined ? { counter: pair.commit } : {}),
277
- ...(pair.slot !== undefined ? { slotCounter: pair.slot } : {}),
278
- ...(prevB64 !== undefined ? { prevB64 } : {}),
279
- epochId: opts.epochId,
280
- };
281
- if (opts.chainId !== undefined) {
282
- (commit as unknown as Record<string, unknown>)["chainId"] = opts.chainId;
283
- }
284
- const proof = await signBody(
285
- key,
286
- { hashAlg: "sha256", digestB64: b64(sha256(bytes)) },
287
- commit,
288
- measurement
289
- );
290
- proofs.push({ proof, bytes, proofHash: computeProofHash(proof), chainHash: computeChainHash(proof) });
291
- }
292
-
293
- return { key, proofs };
294
- }
295
-
296
- /**
297
- * The standard healthy enclave counter sequence: slot 1/commit 2,
298
- * slot 3/commit 4, ... for `length` proofs.
299
- */
300
- export function healthyPairs(length: number): Array<{ slot: string; commit: string }> {
301
- const pairs: Array<{ slot: string; commit: string }> = [];
302
- for (let i = 0; i < length; i++) {
303
- pairs.push({ slot: String(2 * i + 1), commit: String(2 * i + 2) });
304
- }
305
- return pairs;
306
- }
307
-
308
- // ---------------------------------------------------------------------------
309
- // Ethereum anchor fixtures (matching packages/hosted/src/bitcoin-anchor.ts)
310
- // ---------------------------------------------------------------------------
311
-
312
- /**
313
- * Build a verifier-valid Ethereum anchor proof: signed attribution
314
- * name "Ethereum Anchor", message = the block hash string, title = the
315
- * Etherscan block URL, artifact digest = SHA-256 over the block-hash
316
- * STRING (exactly like bitcoin-anchor.ts lines 188-189). Unsigned
317
- * metadata is attached after signing when provided.
318
- */
319
- export async function makeAnchorProof(opts: {
320
- blockHash: string;
321
- blockNumber?: string | number;
322
- /** Overrides the Etherscan URL entirely (for unparseable-title cases). */
323
- title?: string;
324
- /** Omit the title field entirely. */
325
- noTitle?: boolean;
326
- /** Overrides the artifact digest (for digest-binding failure cases; the proof stays validly signed). */
327
- digestB64?: string;
328
- key?: ManualKey;
329
- epochId?: string;
330
- counter?: string;
331
- slotCounter?: string;
332
- prevB64?: string;
333
- chainId?: string;
334
- measurement?: string;
335
- /** Unsigned metadata object attached verbatim after signing. */
336
- metadata?: unknown;
337
- /** Overrides attribution.name (for non-anchor attribution cases). */
338
- attributionName?: string;
339
- random?: RandomSource;
340
- }): Promise<{ proof: BitGraphProof; proofHash: string; chainHash: string; key: ManualKey }> {
341
- const random = opts.random ?? defaultRandom;
342
- const key = opts.key ?? (await makeKey(random));
343
- const commit: BitGraphProof["commit"] = {
344
- nonceB64: b64(random(16)),
345
- ...(opts.counter !== undefined ? { counter: opts.counter } : {}),
346
- ...(opts.slotCounter !== undefined ? { slotCounter: opts.slotCounter } : {}),
347
- ...(opts.prevB64 !== undefined ? { prevB64: opts.prevB64 } : {}),
348
- ...(opts.epochId !== undefined ? { epochId: opts.epochId } : {}),
349
- };
350
- if (opts.chainId !== undefined) {
351
- (commit as unknown as Record<string, unknown>)["chainId"] = opts.chainId;
352
- }
353
- const attribution: { name: string; title?: string; message: string } = {
354
- name: opts.attributionName ?? "Ethereum Anchor",
355
- message: opts.blockHash,
356
- };
357
- if (opts.noTitle !== true) {
358
- attribution.title = opts.title ?? `https://etherscan.io/block/${opts.blockNumber ?? 0}`;
359
- }
360
- const proof = await signBody(
361
- key,
362
- {
363
- hashAlg: "sha256",
364
- digestB64: opts.digestB64 ?? b64(sha256(utf8(opts.blockHash))),
365
- },
366
- commit,
367
- opts.measurement ?? "test-measurement-anchor",
368
- { attribution }
369
- );
370
- if (opts.metadata !== undefined) {
371
- (proof as unknown as Record<string, unknown>)["metadata"] = opts.metadata;
372
- }
373
- return { proof, proofHash: computeProofHash(proof), chainHash: computeChainHash(proof), key };
374
- }
375
-
376
- // ---------------------------------------------------------------------------
377
- // Minimal RLP encoder + synthetic Ethereum block headers (test side only;
378
- // the audit package carries its own independent decoder)
379
- // ---------------------------------------------------------------------------
380
-
381
- export type RlpInput = Uint8Array | RlpInput[];
382
-
383
- export function encodeRlp(item: RlpInput): Uint8Array {
384
- if (item instanceof Uint8Array) {
385
- if (item.length === 1 && (item[0] as number) < 0x80) return item;
386
- return concatBytes([encodeRlpLength(item.length, 0x80), item]);
387
- }
388
- const payload = concatBytes(item.map(encodeRlp));
389
- return concatBytes([encodeRlpLength(payload.length, 0xc0), payload]);
390
- }
391
-
392
- function encodeRlpLength(length: number, offset: number): Uint8Array {
393
- if (length <= 55) return new Uint8Array([offset + length]);
394
- const bytes: number[] = [];
395
- let v = length;
396
- while (v > 0) {
397
- bytes.unshift(v & 0xff);
398
- v = Math.floor(v / 256);
399
- }
400
- return new Uint8Array([offset + 55 + bytes.length, ...bytes]);
401
- }
402
-
403
- /** Minimal big-endian bytes of a non-negative integer; empty for zero (Ethereum header integer encoding). */
404
- export function beBytes(value: number | bigint): Uint8Array {
405
- let v = BigInt(value);
406
- const bytes: number[] = [];
407
- while (v > 0n) {
408
- bytes.unshift(Number(v & 0xffn));
409
- v >>= 8n;
410
- }
411
- return new Uint8Array(bytes);
412
- }
413
-
414
- /**
415
- * Build a synthetic 20-item RLP block header with the number at index 8
416
- * and the timestamp at index 11 (the stable Ethereum header positions).
417
- * Other items are deterministic filler byte strings.
418
- */
419
- export function makeEthereumHeader(opts: {
420
- blockNumber: number | bigint;
421
- timestamp: number | bigint;
422
- itemCount?: number;
423
- }): { headerBytes: Uint8Array; headerRlpHex: string } {
424
- const count = opts.itemCount ?? 20;
425
- const items: RlpInput[] = [];
426
- for (let i = 0; i < count; i++) {
427
- if (i === 8) items.push(beBytes(opts.blockNumber));
428
- else if (i === 11) items.push(beBytes(opts.timestamp));
429
- else items.push(new Uint8Array(32).fill(i + 1));
430
- }
431
- const headerBytes = encodeRlp(items);
432
- return {
433
- headerBytes,
434
- headerRlpHex: `0x${Buffer.from(headerBytes).toString("hex")}`,
435
- };
436
- }
437
-
438
- /** JSON string of a bitgraph-anchor-witness/1 file. */
439
- export function witnessJson(opts: {
440
- headerRlpHex?: unknown;
441
- blockNumber?: unknown;
442
- blockHash?: unknown;
443
- network?: string;
444
- omit?: Array<"headerRlpHex" | "blockNumber" | "blockHash">;
445
- }): string {
446
- const witness: Record<string, unknown> = { version: "bitgraph-anchor-witness/1" };
447
- if (!(opts.omit ?? []).includes("headerRlpHex")) witness["headerRlpHex"] = opts.headerRlpHex;
448
- if (!(opts.omit ?? []).includes("blockNumber")) witness["blockNumber"] = opts.blockNumber;
449
- if (!(opts.omit ?? []).includes("blockHash")) witness["blockHash"] = opts.blockHash;
450
- if (opts.network !== undefined) witness["network"] = opts.network;
451
- return JSON.stringify(witness);
452
- }
453
-
454
- // ---------------------------------------------------------------------------
455
- // Bundle-on-disk helpers
456
- // ---------------------------------------------------------------------------
457
-
458
- export async function makeTempDir(prefix: string): Promise<string> {
459
- return mkdtemp(join(tmpdir(), prefix));
460
- }
461
-
462
- /**
463
- * Write a bundle directory from a path -> content map. Paths use "/"
464
- * separators; parent directories are created as needed.
465
- */
466
- export async function writeBundleDir(
467
- root: string,
468
- files: Record<string, Uint8Array | string>
469
- ): Promise<void> {
470
- for (const [relPath, content] of Object.entries(files)) {
471
- const abs = join(root, ...relPath.split("/"));
472
- await mkdir(dirname(abs), { recursive: true });
473
- await writeFile(abs, typeof content === "string" ? utf8(content) : content);
474
- }
475
- }
476
-
477
- // ---------------------------------------------------------------------------
478
- // Minimal in-memory tar writer
479
- // ---------------------------------------------------------------------------
480
-
481
- export interface TarWriteEntry {
482
- /** Header name field (up to 100 bytes). */
483
- name: string;
484
- content: Uint8Array | string;
485
- /** Defaults to "0" (regular file). */
486
- typeflag?: string;
487
- /** Emit a PAX extended header carrying path=<value> before the entry. */
488
- paxPath?: string;
489
- /**
490
- * Override the size field written in the PAX 'x' header (defaults to the
491
- * real record length). Used by ingest cap tests to declare an absurd
492
- * metadata-entry size without writing that many bytes.
493
- */
494
- paxHeaderDeclaredSize?: number;
495
- /** Emit a GNU long-name ('L') entry carrying this name before the entry. */
496
- gnuLongName?: string;
497
- }
498
-
499
- /** Build a complete tar archive in memory (ustar, PAX, GNU long-name). */
500
- export function makeTar(entries: TarWriteEntry[]): Uint8Array {
501
- const parts: Uint8Array[] = [];
502
- for (const entry of entries) {
503
- const content = typeof entry.content === "string" ? utf8(entry.content) : entry.content;
504
- if (entry.paxPath !== undefined) {
505
- const record = paxRecord("path", entry.paxPath);
506
- const declaredSize = entry.paxHeaderDeclaredSize ?? record.length;
507
- parts.push(tarHeaderBlock("PaxHeaders.0/entry", declaredSize, "x"), padTo512(record));
508
- }
509
- if (entry.gnuLongName !== undefined) {
510
- const nameBytes = utf8(`${entry.gnuLongName}\0`);
511
- parts.push(tarHeaderBlock("././@LongLink", nameBytes.length, "L"), padTo512(nameBytes));
512
- }
513
- parts.push(tarHeaderBlock(entry.name, content.length, entry.typeflag ?? "0"), padTo512(content));
514
- }
515
- parts.push(new Uint8Array(512), new Uint8Array(512));
516
- return concatBytes(parts);
517
- }
518
-
519
- function tarHeaderBlock(name: string, size: number, typeflag: string): Uint8Array {
520
- const block = new Uint8Array(512);
521
- const ascii = (text: string, offset: number, length: number): void => {
522
- const bytes = utf8(text);
523
- block.set(bytes.subarray(0, Math.min(bytes.length, length)), offset);
524
- };
525
- ascii(name, 0, 100);
526
- block.set(octalField(0o644, 8), 100); // mode
527
- block.set(octalField(0, 8), 108); // uid
528
- block.set(octalField(0, 8), 116); // gid
529
- block.set(octalField(size, 12), 124); // size
530
- block.set(octalField(0, 12), 136); // mtime
531
- for (let i = 148; i < 156; i++) block[i] = 0x20; // checksum spaces
532
- block[156] = typeflag.charCodeAt(0);
533
- ascii("ustar", 257, 6); // magic, NUL-terminated by the zero block
534
- ascii("00", 263, 2); // version
535
- let sum = 0;
536
- for (let i = 0; i < 512; i++) sum += block[i] as number;
537
- ascii(sum.toString(8).padStart(6, "0"), 148, 6);
538
- block[154] = 0;
539
- block[155] = 0x20;
540
- return block;
541
- }
542
-
543
- function octalField(value: number, length: number): Uint8Array {
544
- const out = new Uint8Array(length);
545
- const text = value.toString(8).padStart(length - 1, "0");
546
- for (let i = 0; i < text.length; i++) out[i] = text.charCodeAt(i);
547
- out[length - 1] = 0;
548
- return out;
549
- }
550
-
551
- /** PAX record: "<len> <key>=<value>\n" where len counts the whole record. */
552
- function paxRecord(key: string, value: string): Uint8Array {
553
- const baseBytes = utf8(` ${key}=${value}\n`);
554
- let length = baseBytes.length + 1;
555
- while (String(length).length + baseBytes.length !== length) {
556
- length = String(length).length + baseBytes.length;
557
- }
558
- return concatBytes([utf8(String(length)), baseBytes]);
559
- }
560
-
561
- function padTo512(content: Uint8Array): Uint8Array {
562
- const padding = (512 - (content.length % 512)) % 512;
563
- if (padding === 0) return content;
564
- const out = new Uint8Array(content.length + padding);
565
- out.set(content, 0);
566
- return out;
567
- }
568
-
569
- function concatBytes(parts: Uint8Array[]): Uint8Array {
570
- const total = parts.reduce((sum, part) => sum + part.length, 0);
571
- const out = new Uint8Array(total);
572
- let offset = 0;
573
- for (const part of parts) {
574
- out.set(part, offset);
575
- offset += part.length;
576
- }
577
- return out;
578
- }
579
-
580
- // ---------------------------------------------------------------------------
581
- // Serialization helpers
582
- // ---------------------------------------------------------------------------
583
-
584
- /** Compact JSON serialization of a proof, the usual on-disk form. */
585
- export function proofJson(proof: BitGraphProof): string {
586
- return JSON.stringify(proof);
587
- }
588
-
589
- /** Stored form: the proof with a trailing proofHash field, as the ledger serves it. */
590
- export function storedProofJson(proof: BitGraphProof, proofHash: string): string {
591
- return JSON.stringify({ ...proof, proofHash });
592
- }
593
-
594
- // ---------------------------------------------------------------------------
595
- // Standard mixed audit bundle (shared by the report and CLI suites)
596
- // ---------------------------------------------------------------------------
597
-
598
- export interface StandardAuditBundle {
599
- dir: string;
600
- epochId: string;
601
- anchorEpochId: string;
602
- chainId: string;
603
- /** Canonical hashes of the four chain proofs, in chain order, INCLUDING the dropped one. */
604
- chainProofHashes: string[];
605
- /** Canonical hash of the chain proof deliberately absent from the bundle (index 1, slot 3/commit 4). */
606
- droppedProofHash: string;
607
- forkAProofHash: string;
608
- forkBProofHash: string;
609
- anchorProofHash: string;
610
- blockNumber: number;
611
- blockTimestamp: number;
612
- /** Bundle path of the occ/1 reject. */
613
- unsupportedPath: string;
614
- /** Expected counts for assertions. */
615
- expected: {
616
- observed: number;
617
- proofFiles: number;
618
- exactDuplicates: number;
619
- semanticDuplicates: number;
620
- unsupportedVersion: number;
621
- verified: number;
622
- failed: number;
623
- artifactUnavailable: number;
624
- chainless: number;
625
- };
626
- }
627
-
628
- /**
629
- * Build the standard mixed bundle in a temp directory, per the Phase 4d
630
- * brief: a healthy signed chain (4 proofs, slot/commit pairs 1..8) with
631
- * one proof missing (index 1, producing an unexplained-position gap and
632
- * a chain break), a predecessor-reuse fork off the chain tail, an occ/1
633
- * unsupported-version reject, one artifact-present proof (chain genesis)
634
- * and artifact-absent proofs (everything else), an Ethereum anchor in
635
- * its own epoch with a valid offline witness, plus one exact-duplicate
636
- * copy and one semantic-duplicate (stored-form) copy of the genesis.
637
- */
638
- export async function makeStandardAuditBundle(): Promise<StandardAuditBundle> {
639
- const dir = await makeTempDir("bitgraph-audit-standard-");
640
- const epochId = "epoch-standard-main";
641
- const anchorEpochId = "epoch-standard-anchor";
642
- const chainId = "bitgraph:main";
643
- const measurement = "test-measurement-chain";
644
-
645
- const chain = await makeCounterChain({
646
- epochId,
647
- pairs: healthyPairs(4),
648
- chainId,
649
- measurement,
650
- payloadPrefix: "standard-bundle",
651
- });
652
-
653
- const tail = chain.proofs[3]!;
654
- const forkChild = async (slot: string, commit: string, payload: string) => {
655
- const bytes = utf8(payload);
656
- const commitBody: BitGraphProof["commit"] = {
657
- nonceB64: b64(crypto.getRandomValues(new Uint8Array(16))),
658
- counter: commit,
659
- slotCounter: slot,
660
- prevB64: tail.chainHash,
661
- epochId,
662
- };
663
- (commitBody as unknown as Record<string, unknown>)["chainId"] = chainId;
664
- const proof = await signBody(
665
- chain.key,
666
- { hashAlg: "sha256", digestB64: b64(sha256(bytes)) },
667
- commitBody,
668
- measurement
669
- );
670
- return { proof, proofHash: computeProofHash(proof), chainHash: computeChainHash(proof) };
671
- };
672
- const forkA = await forkChild("9", "10", "standard-bundle-fork-a");
673
- const forkB = await forkChild("11", "12", "standard-bundle-fork-b");
674
-
675
- const blockNumber = 123456;
676
- const blockTimestamp = 1_700_000_000;
677
- const { headerBytes, headerRlpHex } = makeEthereumHeader({ blockNumber, timestamp: blockTimestamp });
678
- const blockHash = `0x${Buffer.from(keccak_256(headerBytes)).toString("hex")}`;
679
- const anchor = await makeAnchorProof({
680
- blockHash,
681
- blockNumber,
682
- epochId: anchorEpochId,
683
- counter: "2",
684
- slotCounter: "1",
685
- });
686
-
687
- const unsupportedPath = "legacy/old.json";
688
- const occProof = JSON.stringify({
689
- version: "occ/1",
690
- artifact: { hashAlg: "sha256", digestB64: "b2NjLWxlZ2FjeQ==" },
691
- commit: { nonceB64: "b2NjLW5vbmNl" },
692
- signer: { publicKeyB64: "b2NjLWtleQ==", signatureB64: "b2NjLXNpZw==" },
693
- });
694
-
695
- const genesis = chain.proofs[0]!;
696
- await writeBundleDir(dir, {
697
- "proofs/chain-0.json": proofJson(genesis.proof),
698
- "proofs/chain-0-copy.json": proofJson(genesis.proof),
699
- "proofs/chain-0-stored.json": storedProofJson(genesis.proof, genesis.proofHash),
700
- // chain-1 (slot 3 / commit 4) is deliberately absent: the gap.
701
- "proofs/chain-2.json": proofJson(chain.proofs[2]!.proof),
702
- "proofs/chain-3.json": proofJson(tail.proof),
703
- "proofs/fork-a.json": proofJson(forkA.proof),
704
- "proofs/fork-b.json": proofJson(forkB.proof),
705
- "proofs/anchor.json": proofJson(anchor.proof),
706
- "witnesses/block.json": witnessJson({ headerRlpHex, blockNumber, blockHash }),
707
- "artifacts/payload-0.bin": genesis.bytes,
708
- [unsupportedPath]: occProof,
709
- });
710
-
711
- return {
712
- dir,
713
- epochId,
714
- anchorEpochId,
715
- chainId,
716
- chainProofHashes: chain.proofs.map((p) => p.proofHash),
717
- droppedProofHash: chain.proofs[1]!.proofHash,
718
- forkAProofHash: forkA.proofHash,
719
- forkBProofHash: forkB.proofHash,
720
- anchorProofHash: anchor.proofHash,
721
- blockNumber,
722
- blockTimestamp,
723
- unsupportedPath,
724
- expected: {
725
- observed: 6,
726
- proofFiles: 8,
727
- exactDuplicates: 1,
728
- semanticDuplicates: 1,
729
- unsupportedVersion: 1,
730
- verified: 1,
731
- failed: 0,
732
- artifactUnavailable: 5,
733
- chainless: 0,
734
- },
735
- };
736
- }