@forestrie/merklelog 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +83 -0
  3. package/dist/index.d.ts +21 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +20 -0
  6. package/dist/massifs/indexformat.d.ts +146 -0
  7. package/dist/massifs/indexformat.d.ts.map +1 -0
  8. package/dist/massifs/indexformat.js +191 -0
  9. package/dist/massifs/logformat.d.ts +49 -0
  10. package/dist/massifs/logformat.d.ts.map +1 -0
  11. package/dist/massifs/logformat.js +49 -0
  12. package/dist/massifs/massif.d.ts +86 -0
  13. package/dist/massifs/massif.d.ts.map +1 -0
  14. package/dist/massifs/massif.js +143 -0
  15. package/dist/massifs/massiffull.d.ts +14 -0
  16. package/dist/massifs/massiffull.d.ts.map +1 -0
  17. package/dist/massifs/massiffull.js +21 -0
  18. package/dist/massifs/massiflogentries.d.ts +23 -0
  19. package/dist/massifs/massiflogentries.d.ts.map +1 -0
  20. package/dist/massifs/massiflogentries.js +31 -0
  21. package/dist/massifs/massifstart.d.ts +63 -0
  22. package/dist/massifs/massifstart.d.ts.map +1 -0
  23. package/dist/massifs/massifstart.js +39 -0
  24. package/dist/massifs/mmrindex.d.ts +15 -0
  25. package/dist/massifs/mmrindex.d.ts.map +1 -0
  26. package/dist/massifs/mmrindex.js +24 -0
  27. package/dist/massifs/peakstackend.d.ts +21 -0
  28. package/dist/massifs/peakstackend.d.ts.map +1 -0
  29. package/dist/massifs/peakstackend.js +29 -0
  30. package/dist/massifs/types.d.ts +20 -0
  31. package/dist/massifs/types.d.ts.map +1 -0
  32. package/dist/massifs/types.js +23 -0
  33. package/dist/massifs/urkleindex.d.ts +116 -0
  34. package/dist/massifs/urkleindex.d.ts.map +1 -0
  35. package/dist/massifs/urkleindex.js +169 -0
  36. package/dist/massifs/v2storagepaths.d.ts +17 -0
  37. package/dist/massifs/v2storagepaths.d.ts.map +1 -0
  38. package/dist/massifs/v2storagepaths.js +46 -0
  39. package/dist/mmr/algorithms-sync.d.ts +17 -0
  40. package/dist/mmr/algorithms-sync.d.ts.map +1 -0
  41. package/dist/mmr/algorithms-sync.js +42 -0
  42. package/dist/mmr/algorithms.d.ts +79 -0
  43. package/dist/mmr/algorithms.d.ts.map +1 -0
  44. package/dist/mmr/algorithms.js +155 -0
  45. package/dist/mmr/index.d.ts +37 -0
  46. package/dist/mmr/index.d.ts.map +1 -0
  47. package/dist/mmr/index.js +64 -0
  48. package/dist/mmr/math.d.ts +67 -0
  49. package/dist/mmr/math.d.ts.map +1 -0
  50. package/dist/mmr/math.js +172 -0
  51. package/dist/mmr/types.d.ts +37 -0
  52. package/dist/mmr/types.d.ts.map +1 -0
  53. package/dist/mmr/types.js +4 -0
  54. package/dist/uint64/index.d.ts +90 -0
  55. package/dist/uint64/index.d.ts.map +1 -0
  56. package/dist/uint64/index.js +149 -0
  57. package/dist/utils/arrays.d.ts +15 -0
  58. package/dist/utils/arrays.d.ts.map +1 -0
  59. package/dist/utils/arrays.js +24 -0
  60. package/package.json +41 -0
  61. package/src/index.ts +68 -0
  62. package/src/massifs/indexformat.ts +217 -0
  63. package/src/massifs/logformat.ts +54 -0
  64. package/src/massifs/massif.ts +182 -0
  65. package/src/massifs/massiffull.ts +28 -0
  66. package/src/massifs/massiflogentries.ts +40 -0
  67. package/src/massifs/massifstart.ts +67 -0
  68. package/src/massifs/mmrindex.ts +32 -0
  69. package/src/massifs/peakstackend.ts +34 -0
  70. package/src/massifs/types.ts +55 -0
  71. package/src/massifs/urkleindex.ts +273 -0
  72. package/src/massifs/v2storagepaths.ts +61 -0
  73. package/src/mmr/algorithms-sync.ts +46 -0
  74. package/src/mmr/algorithms.ts +194 -0
  75. package/src/mmr/index.ts +75 -0
  76. package/src/mmr/math.ts +190 -0
  77. package/src/mmr/types.ts +39 -0
  78. package/src/uint64/index.ts +164 -0
  79. package/src/utils/arrays.ts +25 -0
@@ -0,0 +1,86 @@
1
+ import type { MassifStart } from "./massifstart.js";
2
+ /**
3
+ * Massif - Efficient buffer-based access to massif data
4
+ *
5
+ * Provides efficient access to massif start data based on a view of an
6
+ * in-memory buffer which holds the data. All operations work directly with
7
+ * the buffer without copying.
8
+ */
9
+ export declare class Massif {
10
+ private readonly buffer;
11
+ /**
12
+ * Creates a new Massif instance from buffer data
13
+ * @param data - The massif data as ArrayBuffer, Uint8Array, or Buffer
14
+ */
15
+ constructor(data: ArrayBuffer | Uint8Array | Buffer | {
16
+ buffer: ArrayBuffer;
17
+ byteOffset: number;
18
+ byteLength: number;
19
+ });
20
+ /**
21
+ * Returns a MassifStart instance populated by reading directly from the buffer
22
+ *
23
+ * Computes firstIndex using massif height and index (calls MMR function)
24
+ * Computes peakStackLen using massif index (calls MMR function)
25
+ */
26
+ getStart(): MassifStart;
27
+ /**
28
+ * Returns a buffer view of the corresponding field at zero-based index
29
+ *
30
+ * Each field is 32 bytes (LogFormat.ValueBytes). Zero-based indexing, without regard
31
+ * to peakstack or trieindex structure.
32
+ *
33
+ * @param index - Zero-based field index (Number or BigInt)
34
+ * @param count - Number of consecutive fields to include in the view (defaults to 1)
35
+ * @returns Uint8Array view of the field(s) (32 bytes per field)
36
+ */
37
+ fieldref(index: number | bigint, count?: number): Uint8Array;
38
+ /**
39
+ * Reads bytes from the buffer at the specified offset
40
+ *
41
+ * Returns a view of the buffer without copying. Efficient for reading
42
+ * arbitrary byte ranges that may span multiple 32-byte fields.
43
+ *
44
+ * @param offset - Byte offset into the buffer
45
+ * @param length - Number of bytes to read
46
+ * @returns Uint8Array view of the requested bytes
47
+ */
48
+ readBytes(offset: number, length: number): Uint8Array;
49
+ /**
50
+ * Reads a big-endian uint64 from the buffer
51
+ */
52
+ private readUint64BE;
53
+ /**
54
+ * Reads a big-endian uint32 from the buffer
55
+ */
56
+ private readUint32BE;
57
+ /**
58
+ * Reads a big-endian uint16 from the buffer
59
+ */
60
+ private readUint16BE;
61
+ /**
62
+ * Reserved field (bytes 0-7)
63
+ */
64
+ get reserved(): bigint;
65
+ /**
66
+ * Last ID timestamp (bytes 8-15)
67
+ */
68
+ get lastID(): bigint;
69
+ /**
70
+ * Version (bytes 21-22)
71
+ */
72
+ get version(): number;
73
+ /**
74
+ * Commitment epoch (bytes 23-26)
75
+ */
76
+ get commitmentEpoch(): number;
77
+ /**
78
+ * Massif height (byte 27)
79
+ */
80
+ get massifHeight(): number;
81
+ /**
82
+ * Massif index (bytes 28-31)
83
+ */
84
+ get massifIndex(): number;
85
+ }
86
+ //# sourceMappingURL=massif.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"massif.d.ts","sourceRoot":"","sources":["../../src/massifs/massif.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAKpD;;;;;;GAMG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IAEpC;;;OAGG;gBAED,IAAI,EACA,WAAW,GACX,UAAU,GACV,MAAM,GACN;QAAE,MAAM,EAAE,WAAW,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;IAsBrE;;;;;OAKG;IACH,QAAQ,IAAI,WAAW;IAsBvB;;;;;;;;;OASG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,UAAU;IAM/D;;;;;;;;;OASG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU;IAIrD;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;OAEG;IACH,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED;;OAEG;IACH,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED;;OAEG;IACH,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;CACF"}
@@ -0,0 +1,143 @@
1
+ import { MassifStartFmt } from "./massifstart.js";
2
+ import { LogFormat } from "./logformat.js";
3
+ import { massifFirstLeaf, leafMinusSpurSum } from "../mmr/index.js";
4
+ /**
5
+ * Massif - Efficient buffer-based access to massif data
6
+ *
7
+ * Provides efficient access to massif start data based on a view of an
8
+ * in-memory buffer which holds the data. All operations work directly with
9
+ * the buffer without copying.
10
+ */
11
+ export class Massif {
12
+ buffer;
13
+ /**
14
+ * Creates a new Massif instance from buffer data
15
+ * @param data - The massif data as ArrayBuffer, Uint8Array, or Buffer
16
+ */
17
+ constructor(data) {
18
+ if (data instanceof ArrayBuffer) {
19
+ this.buffer = new Uint8Array(data);
20
+ }
21
+ else if (data instanceof Uint8Array) {
22
+ this.buffer = data;
23
+ }
24
+ else if ("buffer" in data &&
25
+ "byteOffset" in data &&
26
+ "byteLength" in data) {
27
+ // Node.js Buffer or similar
28
+ this.buffer = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
29
+ }
30
+ else {
31
+ throw new Error("Unsupported buffer type");
32
+ }
33
+ }
34
+ /**
35
+ * Returns a MassifStart instance populated by reading directly from the buffer
36
+ *
37
+ * Computes firstIndex using massif height and index (calls MMR function)
38
+ * Computes peakStackLen using massif index (calls MMR function)
39
+ */
40
+ getStart() {
41
+ const massifHeight = this.massifHeight;
42
+ const massifIndex = this.massifIndex;
43
+ // Compute firstIndex using massif height and index
44
+ const firstIndex = massifFirstLeaf(massifHeight, massifIndex);
45
+ // Compute peakStackLen using massif index
46
+ const peakStackLen = leafMinusSpurSum(BigInt(massifIndex));
47
+ return {
48
+ reserved: this.reserved,
49
+ lastID: this.lastID,
50
+ version: this.version,
51
+ commitmentEpoch: this.commitmentEpoch,
52
+ massifHeight,
53
+ massifIndex,
54
+ firstIndex,
55
+ peakStackLen,
56
+ };
57
+ }
58
+ /**
59
+ * Returns a buffer view of the corresponding field at zero-based index
60
+ *
61
+ * Each field is 32 bytes (LogFormat.ValueBytes). Zero-based indexing, without regard
62
+ * to peakstack or trieindex structure.
63
+ *
64
+ * @param index - Zero-based field index (Number or BigInt)
65
+ * @param count - Number of consecutive fields to include in the view (defaults to 1)
66
+ * @returns Uint8Array view of the field(s) (32 bytes per field)
67
+ */
68
+ fieldref(index, count = 1) {
69
+ const idx = typeof index === "bigint" ? Number(index) : index;
70
+ const offset = idx * LogFormat.ValueBytes;
71
+ return this.buffer.slice(offset, offset + count * LogFormat.ValueBytes);
72
+ }
73
+ /**
74
+ * Reads bytes from the buffer at the specified offset
75
+ *
76
+ * Returns a view of the buffer without copying. Efficient for reading
77
+ * arbitrary byte ranges that may span multiple 32-byte fields.
78
+ *
79
+ * @param offset - Byte offset into the buffer
80
+ * @param length - Number of bytes to read
81
+ * @returns Uint8Array view of the requested bytes
82
+ */
83
+ readBytes(offset, length) {
84
+ return this.buffer.slice(offset, offset + length);
85
+ }
86
+ /**
87
+ * Reads a big-endian uint64 from the buffer
88
+ */
89
+ readUint64BE(offset) {
90
+ const view = new DataView(this.buffer.buffer, this.buffer.byteOffset + offset, 8);
91
+ return view.getBigUint64(0, false); // false = big-endian
92
+ }
93
+ /**
94
+ * Reads a big-endian uint32 from the buffer
95
+ */
96
+ readUint32BE(offset) {
97
+ const view = new DataView(this.buffer.buffer, this.buffer.byteOffset + offset, 4);
98
+ return view.getUint32(0, false); // false = big-endian
99
+ }
100
+ /**
101
+ * Reads a big-endian uint16 from the buffer
102
+ */
103
+ readUint16BE(offset) {
104
+ const view = new DataView(this.buffer.buffer, this.buffer.byteOffset + offset, 2);
105
+ return view.getUint16(0, false); // false = big-endian
106
+ }
107
+ /**
108
+ * Reserved field (bytes 0-7)
109
+ */
110
+ get reserved() {
111
+ return this.readUint64BE(0);
112
+ }
113
+ /**
114
+ * Last ID timestamp (bytes 8-15)
115
+ */
116
+ get lastID() {
117
+ return this.readUint64BE(MassifStartFmt.LastIdFirstByte);
118
+ }
119
+ /**
120
+ * Version (bytes 21-22)
121
+ */
122
+ get version() {
123
+ return this.readUint16BE(MassifStartFmt.VersionFirstByte);
124
+ }
125
+ /**
126
+ * Commitment epoch (bytes 23-26)
127
+ */
128
+ get commitmentEpoch() {
129
+ return this.readUint32BE(MassifStartFmt.EpochFirstByte);
130
+ }
131
+ /**
132
+ * Massif height (byte 27)
133
+ */
134
+ get massifHeight() {
135
+ return this.buffer[MassifStartFmt.MassifHeightFirstByte];
136
+ }
137
+ /**
138
+ * Massif index (bytes 28-31)
139
+ */
140
+ get massifIndex() {
141
+ return this.readUint32BE(MassifStartFmt.MassifFirstByte);
142
+ }
143
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Massif fullness determination functions
3
+ *
4
+ * Functions for determining if a massif is full based on its height and log entries.
5
+ */
6
+ /**
7
+ * Determine if a massif is full.
8
+ *
9
+ * @param massifHeight - Massif height (1-based)
10
+ * @param logEntries - Number of log entries (nodes) in the massif
11
+ * @returns True if the massif is full
12
+ */
13
+ export declare function isMassifFull(massifHeight: number, logEntries: bigint): boolean;
14
+ //# sourceMappingURL=massiffull.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"massiffull.d.ts","sourceRoot":"","sources":["../../src/massifs/massiffull.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAWT"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Massif fullness determination functions
3
+ *
4
+ * Functions for determining if a massif is full based on its height and log entries.
5
+ */
6
+ /**
7
+ * Determine if a massif is full.
8
+ *
9
+ * @param massifHeight - Massif height (1-based)
10
+ * @param logEntries - Number of log entries (nodes) in the massif
11
+ * @returns True if the massif is full
12
+ */
13
+ export function isMassifFull(massifHeight, logEntries) {
14
+ // Convert 1-based height to 0-based height index
15
+ const heightIndex = massifHeight - 1;
16
+ // Expected number of leaves for a full massif: f = 2^g = 1 << heightIndex
17
+ const expectedLeaves = BigInt(1 << heightIndex);
18
+ // Actual number of leaves: f = (n + 1) / 2
19
+ const actualLeaves = (logEntries + 1n) >> 1n;
20
+ return actualLeaves >= expectedLeaves;
21
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * MassifLogEntries calculation for v2 massif format
3
+ */
4
+ /**
5
+ * MassifLogEntries calculates the number of log entries (nodes) in a blob from
6
+ * the length of the blob in bytes.
7
+ *
8
+ * It does this by accounting for the index data and other header data.
9
+ * If you know the FirstIndex from the massif start header you can get the
10
+ * overall mmr size by direct addition.
11
+ *
12
+ * Note: this function exists so we can compute the mmrSize from just the blob
13
+ * store metadata: we store the FirstIndex on a blob tag, and the blob
14
+ * metadata includes ContentLength. This means when we are checking if a root
15
+ * seal covers the current log head, we don't need to fetch the log massif blob.
16
+ *
17
+ * @param dataLen - Total length of the massif blob in bytes
18
+ * @param massifHeight - One-based massif height
19
+ * @returns Number of log entries (nodes) in the blob
20
+ * @throws Error if the data length is too short to contain the required headers
21
+ */
22
+ export declare function massifLogEntries(dataLen: number, massifHeight: number): bigint;
23
+ //# sourceMappingURL=massiflogentries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"massiflogentries.d.ts","sourceRoot":"","sources":["../../src/massifs/massiflogentries.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,MAAM,CAWR"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * MassifLogEntries calculation for v2 massif format
3
+ */
4
+ import { LogFormat } from "./logformat.js";
5
+ import { peakStackEnd } from "./peakstackend.js";
6
+ /**
7
+ * MassifLogEntries calculates the number of log entries (nodes) in a blob from
8
+ * the length of the blob in bytes.
9
+ *
10
+ * It does this by accounting for the index data and other header data.
11
+ * If you know the FirstIndex from the massif start header you can get the
12
+ * overall mmr size by direct addition.
13
+ *
14
+ * Note: this function exists so we can compute the mmrSize from just the blob
15
+ * store metadata: we store the FirstIndex on a blob tag, and the blob
16
+ * metadata includes ContentLength. This means when we are checking if a root
17
+ * seal covers the current log head, we don't need to fetch the log massif blob.
18
+ *
19
+ * @param dataLen - Total length of the massif blob in bytes
20
+ * @param massifHeight - One-based massif height
21
+ * @returns Number of log entries (nodes) in the blob
22
+ * @throws Error if the data length is too short to contain the required headers
23
+ */
24
+ export function massifLogEntries(dataLen, massifHeight) {
25
+ const stackEnd = peakStackEnd(massifHeight);
26
+ if (BigInt(dataLen) < stackEnd) {
27
+ throw new Error(`Massif data length ${dataLen} is too short. Minimum required: ${stackEnd} bytes`);
28
+ }
29
+ const mmrByteCount = BigInt(dataLen) - stackEnd;
30
+ return mmrByteCount / BigInt(LogFormat.ValueBytes);
31
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * MassifStart - Header information for a massif blob
3
+ *
4
+ * The massif start is a 32-byte field encoding bookkeeping information
5
+ * required in a blob to allow for efficient correctness checks.
6
+ */
7
+ export interface MassifStart {
8
+ /** Reserved field (bytes 0-7) */
9
+ reserved: bigint;
10
+ /** Last ID timestamp (bytes 8-15) */
11
+ lastID: bigint;
12
+ /** Version (bytes 21-22) */
13
+ version: number;
14
+ /** Commitment epoch (bytes 23-26) */
15
+ commitmentEpoch: number;
16
+ /** Massif height (byte 27) */
17
+ massifHeight: number;
18
+ /** Massif index (bytes 28-31) */
19
+ massifIndex: number;
20
+ /** First MMR index in this massif (computed) */
21
+ firstIndex: bigint;
22
+ /** Peak stack length (computed) */
23
+ peakStackLen: bigint;
24
+ }
25
+ /**
26
+ * MassifStartFmt - Format constants for MassifStart fields
27
+ *
28
+ * Byte offsets and sizes for MassifStart fields.
29
+ * Matching the Go implementation in go-merklelog/massifs/massifstart.go
30
+ */
31
+ export declare namespace MassifStartFmt {
32
+ /** Last ID timestamp field - first byte offset */
33
+ const LastIdFirstByte = 8;
34
+ /** Last ID timestamp field - size in bytes */
35
+ const LastIdSize = 8;
36
+ /** Last ID timestamp field - end byte offset */
37
+ const LastIdEnd: number;
38
+ /** Version field - first byte offset */
39
+ const VersionFirstByte = 21;
40
+ /** Version field - size in bytes */
41
+ const VersionSize = 2;
42
+ /** Version field - end byte offset */
43
+ const VersionEnd: number;
44
+ /** Commitment epoch field - first byte offset */
45
+ const EpochFirstByte: number;
46
+ /** Commitment epoch field - size in bytes */
47
+ const EpochSize = 4;
48
+ /** Commitment epoch field - end byte offset */
49
+ const EpochEnd: number;
50
+ /** Massif height field - first byte offset */
51
+ const MassifHeightFirstByte: number;
52
+ /** Massif height field - size in bytes */
53
+ const MassifHeightSize = 1;
54
+ /** Massif height field - end byte offset */
55
+ const MassifHeightEnd: number;
56
+ /** Massif index field - first byte offset */
57
+ const MassifFirstByte: number;
58
+ /** Massif index field - size in bytes */
59
+ const MassifSize = 4;
60
+ /** Massif index field - end byte offset */
61
+ const MassifEnd: number;
62
+ }
63
+ //# sourceMappingURL=massifstart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"massifstart.d.ts","sourceRoot":"","sources":["../../src/massifs/massifstart.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,eAAe,EAAE,MAAM,CAAC;IACxB,8BAA8B;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,yBAAiB,cAAc,CAAC;IAC9B,kDAAkD;IAC3C,MAAM,eAAe,IAAI,CAAC;IACjC,8CAA8C;IACvC,MAAM,UAAU,IAAI,CAAC;IAC5B,gDAAgD;IACzC,MAAM,SAAS,QAA+B,CAAC;IAEtD,wCAAwC;IACjC,MAAM,gBAAgB,KAAK,CAAC;IACnC,oCAAoC;IAC7B,MAAM,WAAW,IAAI,CAAC;IAC7B,sCAAsC;IAC/B,MAAM,UAAU,QAAiC,CAAC;IAEzD,iDAAiD;IAC1C,MAAM,cAAc,QAAa,CAAC;IACzC,6CAA6C;IACtC,MAAM,SAAS,IAAI,CAAC;IAC3B,+CAA+C;IACxC,MAAM,QAAQ,QAA6B,CAAC;IAEnD,8CAA8C;IACvC,MAAM,qBAAqB,QAAW,CAAC;IAC9C,0CAA0C;IACnC,MAAM,gBAAgB,IAAI,CAAC;IAClC,4CAA4C;IACrC,MAAM,eAAe,QAA2C,CAAC;IAExE,6CAA6C;IACtC,MAAM,eAAe,QAAkB,CAAC;IAC/C,yCAAyC;IAClC,MAAM,UAAU,IAAI,CAAC;IAC5B,2CAA2C;IACpC,MAAM,SAAS,QAA+B,CAAC;CACvD"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * MassifStartFmt - Format constants for MassifStart fields
3
+ *
4
+ * Byte offsets and sizes for MassifStart fields.
5
+ * Matching the Go implementation in go-merklelog/massifs/massifstart.go
6
+ */
7
+ export var MassifStartFmt;
8
+ (function (MassifStartFmt) {
9
+ /** Last ID timestamp field - first byte offset */
10
+ MassifStartFmt.LastIdFirstByte = 8;
11
+ /** Last ID timestamp field - size in bytes */
12
+ MassifStartFmt.LastIdSize = 8;
13
+ /** Last ID timestamp field - end byte offset */
14
+ MassifStartFmt.LastIdEnd = MassifStartFmt.LastIdFirstByte + MassifStartFmt.LastIdSize;
15
+ /** Version field - first byte offset */
16
+ MassifStartFmt.VersionFirstByte = 21;
17
+ /** Version field - size in bytes */
18
+ MassifStartFmt.VersionSize = 2;
19
+ /** Version field - end byte offset */
20
+ MassifStartFmt.VersionEnd = MassifStartFmt.VersionFirstByte + MassifStartFmt.VersionSize;
21
+ /** Commitment epoch field - first byte offset */
22
+ MassifStartFmt.EpochFirstByte = MassifStartFmt.VersionEnd; // 23
23
+ /** Commitment epoch field - size in bytes */
24
+ MassifStartFmt.EpochSize = 4;
25
+ /** Commitment epoch field - end byte offset */
26
+ MassifStartFmt.EpochEnd = MassifStartFmt.EpochFirstByte + MassifStartFmt.EpochSize;
27
+ /** Massif height field - first byte offset */
28
+ MassifStartFmt.MassifHeightFirstByte = MassifStartFmt.EpochEnd; // 27
29
+ /** Massif height field - size in bytes */
30
+ MassifStartFmt.MassifHeightSize = 1;
31
+ /** Massif height field - end byte offset */
32
+ MassifStartFmt.MassifHeightEnd = MassifStartFmt.MassifHeightFirstByte + MassifStartFmt.MassifHeightSize;
33
+ /** Massif index field - first byte offset */
34
+ MassifStartFmt.MassifFirstByte = MassifStartFmt.MassifHeightEnd; // 28
35
+ /** Massif index field - size in bytes */
36
+ MassifStartFmt.MassifSize = 4;
37
+ /** Massif index field - end byte offset */
38
+ MassifStartFmt.MassifEnd = MassifStartFmt.MassifFirstByte + MassifStartFmt.MassifSize;
39
+ })(MassifStartFmt || (MassifStartFmt = {}));
@@ -0,0 +1,15 @@
1
+ /**
2
+ * MMR index calculation functions for massifs
3
+ *
4
+ * Functions for computing MMR indices from massif metadata.
5
+ */
6
+ /**
7
+ * Compute the last MMR index in a massif.
8
+ *
9
+ * @param massifHeight - Massif height (1-based)
10
+ * @param massifIndex - Massif index
11
+ * @param blobSize - Size of the massif blob in bytes
12
+ * @returns The last MMR index in the massif
13
+ */
14
+ export declare function computeLastMMRIndex(massifHeight: number, massifIndex: number, blobSize: number): bigint;
15
+ //# sourceMappingURL=mmrindex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mmrindex.d.ts","sourceRoot":"","sources":["../../src/massifs/mmrindex.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,MAAM,CAUR"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * MMR index calculation functions for massifs
3
+ *
4
+ * Functions for computing MMR indices from massif metadata.
5
+ */
6
+ import { massifLogEntries } from "./massiflogentries.js";
7
+ import { massifFirstLeaf } from "../mmr/index.js";
8
+ /**
9
+ * Compute the last MMR index in a massif.
10
+ *
11
+ * @param massifHeight - Massif height (1-based)
12
+ * @param massifIndex - Massif index
13
+ * @param blobSize - Size of the massif blob in bytes
14
+ * @returns The last MMR index in the massif
15
+ */
16
+ export function computeLastMMRIndex(massifHeight, massifIndex, blobSize) {
17
+ // Calculate number of log entries (nodes) in the blob
18
+ // massifLogEntries expects 1-based height
19
+ const logEntries = massifLogEntries(blobSize, massifHeight);
20
+ // Get firstIndex using massifFirstLeaf (also expects 1-based height)
21
+ const firstIndex = massifFirstLeaf(massifHeight, massifIndex);
22
+ // Last index = firstIndex + logEntries - 1
23
+ return firstIndex + logEntries - 1n;
24
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * PeakStackEnd calculation for v2 massif format
3
+ */
4
+ /**
5
+ * PeakStackEnd returns the first byte after the massif ancestor peak stack data
6
+ *
7
+ * The peak stack is fixed at MaxMmrHeight entries regardless of how many are
8
+ * actually needed. This makes it possible to trivially compute the node &
9
+ * leaf counts knowing only the byte size of the massif.
10
+ *
11
+ * V2 layout:
12
+ * StartHeader (256 bytes)
13
+ * IndexHeader (32 bytes) = BloomHeaderV1
14
+ * IndexData (bloom bitsets + frontier + leaf table + node store)
15
+ * PeakStack (MaxMmrHeight * ValueBytes = 2048 bytes)
16
+ *
17
+ * @param massifHeight - One-based massif height
18
+ * @returns Byte offset of the end of the peak stack
19
+ */
20
+ export declare function peakStackEnd(massifHeight: number): bigint;
21
+ //# sourceMappingURL=peakstackend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peakstackend.d.ts","sourceRoot":"","sources":["../../src/massifs/peakstackend.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAUzD"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * PeakStackEnd calculation for v2 massif format
3
+ */
4
+ import { LogFormat } from "./logformat.js";
5
+ import { indexDataBytesV2, leafCountForMassifHeight } from "./indexformat.js";
6
+ /**
7
+ * PeakStackEnd returns the first byte after the massif ancestor peak stack data
8
+ *
9
+ * The peak stack is fixed at MaxMmrHeight entries regardless of how many are
10
+ * actually needed. This makes it possible to trivially compute the node &
11
+ * leaf counts knowing only the byte size of the massif.
12
+ *
13
+ * V2 layout:
14
+ * StartHeader (256 bytes)
15
+ * IndexHeader (32 bytes) = BloomHeaderV1
16
+ * IndexData (bloom bitsets + frontier + leaf table + node store)
17
+ * PeakStack (MaxMmrHeight * ValueBytes = 2048 bytes)
18
+ *
19
+ * @param massifHeight - One-based massif height
20
+ * @returns Byte offset of the end of the peak stack
21
+ */
22
+ export function peakStackEnd(massifHeight) {
23
+ const fixedHeaderEnd = BigInt(LogFormat.StartHeaderSize);
24
+ const indexHeaderBytes = BigInt(LogFormat.IndexHeaderBytes);
25
+ const leafCount = leafCountForMassifHeight(massifHeight);
26
+ const indexDataBytes = indexDataBytesV2(leafCount);
27
+ const peakStackSize = BigInt(LogFormat.MaxMmrHeight * LogFormat.ValueBytes);
28
+ return fixedHeaderEnd + indexHeaderBytes + indexDataBytes + peakStackSize;
29
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Re-exports for massifs module types and constants
3
+ *
4
+ * This file serves as a convenience re-export point for external consumers.
5
+ * Types and interfaces are organized into individual files to:
6
+ * 1. Avoid circular dependencies
7
+ * 2. Avoid monolithic types.ts files
8
+ * 3. Keep related code (interfaces and their implementations) together
9
+ */
10
+ export type { MassifStart } from "./massifstart.js";
11
+ export { MassifStartFmt } from "./massifstart.js";
12
+ export { LogFormat } from "./logformat.js";
13
+ export { Urkle, Bloom, IndexV2, leafCountForMassifHeight, leafTableBytes, nodeCountMax, nodeStoreBytes, bloomMBits, bloomBitsetBytes, bloomRegionBytes, indexDataBytesV2, } from "./indexformat.js";
14
+ export { peakStackEnd } from "./peakstackend.js";
15
+ export { massifLogEntries } from "./massiflogentries.js";
16
+ export { urkleLeafTableStartFieldIndex, urkleLeafTableStartByteOffset, createLeafEnumerator, leafComponentByteOffset, leafComponentSize, } from "./urkleindex.js";
17
+ export type { LeafComponent, LeafEnumeratorSpec, LeafEntry, } from "./urkleindex.js";
18
+ export { computeLastMMRIndex } from "./mmrindex.js";
19
+ export { isMassifFull } from "./massiffull.js";
20
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/massifs/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,EACL,KAAK,EACL,KAAK,EACL,OAAO,EACP,wBAAwB,EACxB,cAAc,EACd,YAAY,EACZ,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EACL,6BAA6B,EAC7B,6BAA6B,EAC7B,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,SAAS,GACV,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGpD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Re-exports for massifs module types and constants
3
+ *
4
+ * This file serves as a convenience re-export point for external consumers.
5
+ * Types and interfaces are organized into individual files to:
6
+ * 1. Avoid circular dependencies
7
+ * 2. Avoid monolithic types.ts files
8
+ * 3. Keep related code (interfaces and their implementations) together
9
+ */
10
+ export { MassifStartFmt } from "./massifstart.js";
11
+ // Re-export log format constants
12
+ export { LogFormat } from "./logformat.js";
13
+ // Re-export index format constants and functions (v2)
14
+ export { Urkle, Bloom, IndexV2, leafCountForMassifHeight, leafTableBytes, nodeCountMax, nodeStoreBytes, bloomMBits, bloomBitsetBytes, bloomRegionBytes, indexDataBytesV2, } from "./indexformat.js";
15
+ // Re-export peakStackEnd and massifLogEntries
16
+ export { peakStackEnd } from "./peakstackend.js";
17
+ export { massifLogEntries } from "./massiflogentries.js";
18
+ // Re-export urkle index helpers
19
+ export { urkleLeafTableStartFieldIndex, urkleLeafTableStartByteOffset, createLeafEnumerator, leafComponentByteOffset, leafComponentSize, } from "./urkleindex.js";
20
+ // Re-export MMR index functions
21
+ export { computeLastMMRIndex } from "./mmrindex.js";
22
+ // Re-export massif fullness functions
23
+ export { isMassifFull } from "./massiffull.js";