@forestrie/merklelog 0.6.0 → 0.7.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.
package/dist/index.d.ts CHANGED
@@ -12,6 +12,7 @@ export type { MassifStart, LeafComponent, LeafEnumeratorSpec, LeafEntry, } from
12
12
  export { MassifStartFmt } from "./massifs/types.js";
13
13
  export { LogFormat, Urkle, Bloom, IndexV2, leafCountForMassifHeight, leafTableBytes, nodeCountMax, nodeStoreBytes, bloomMBits, bloomBitsetBytes, bloomRegionBytes, indexDataBytesV2, peakStackEnd, massifLogEntries, urkleLeafTableStartFieldIndex, urkleLeafTableStartByteOffset, createLeafEnumerator, leafComponentByteOffset, leafComponentSize, computeLastMMRIndex, isMassifFull, } from "./massifs/types.js";
14
14
  export { formatMassifObjectIndex, MASSIF_OBJECT_INDEX_DIGITS, MAX_MASSIF_INDEX, parseV2StorageObjectPath, v2CheckpointObjectKey, v2MassifObjectKey, } from "./massifs/v2storagepaths.js";
15
+ export { massifIndexFromLeafIndex } from "./massifs/massifindex.js";
15
16
  export { openMassifNodeStore } from "./massifs/nodestore.js";
16
17
  export type { MassifNodeStore } from "./massifs/nodestore.js";
17
18
  export { openMassifLeafIndex, MissingIndexError } from "./massifs/leafindex.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,YAAY,EACV,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,SAAS,GACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EACL,SAAS,EACT,KAAK,EACL,KAAK,EACL,OAAO,EACP,wBAAwB,EACxB,cAAc,EACd,YAAY,EACZ,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,6BAA6B,EAC7B,6BAA6B,EAC7B,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,GACb,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,gBAAgB,EAChB,wBAAwB,EACxB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChF,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG3E,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EACL,WAAW,EACX,MAAM,EACN,qBAAqB,EACrB,SAAS,EACT,WAAW,EACX,sBAAsB,EACtB,SAAS,EACT,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,QAAQ,EACR,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,qBAAqB,EACrB,KAAK,gBAAgB,GACtB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,4BAA4B,EAC5B,6BAA6B,EAC7B,wBAAwB,EACxB,uBAAuB,EACvB,gBAAgB,EAChB,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAClD,YAAY,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAG7C,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,yBAAyB,EACzB,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,uBAAuB,EACvB,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,YAAY,EACV,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,SAAS,GACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EACL,SAAS,EACT,KAAK,EACL,KAAK,EACL,OAAO,EACP,wBAAwB,EACxB,cAAc,EACd,YAAY,EACZ,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,6BAA6B,EAC7B,6BAA6B,EAC7B,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,GACb,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,gBAAgB,EAChB,wBAAwB,EACxB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChF,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG3E,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EACL,WAAW,EACX,MAAM,EACN,qBAAqB,EACrB,SAAS,EACT,WAAW,EACX,sBAAsB,EACtB,SAAS,EACT,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,QAAQ,EACR,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,qBAAqB,EACrB,KAAK,gBAAgB,GACtB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,4BAA4B,EAC5B,6BAA6B,EAC7B,wBAAwB,EACxB,uBAAuB,EACvB,gBAAgB,EAChB,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAClD,YAAY,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAG7C,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,yBAAyB,EACzB,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,uBAAuB,EACvB,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ export { MassifStartFmt } from "./massifs/types.js";
14
14
  export { LogFormat, Urkle, Bloom, IndexV2, leafCountForMassifHeight, leafTableBytes, nodeCountMax, nodeStoreBytes, bloomMBits, bloomBitsetBytes, bloomRegionBytes, indexDataBytesV2, peakStackEnd, massifLogEntries, urkleLeafTableStartFieldIndex, urkleLeafTableStartByteOffset, createLeafEnumerator, leafComponentByteOffset, leafComponentSize, computeLastMMRIndex, isMassifFull, } from "./massifs/types.js";
15
15
  export { formatMassifObjectIndex, MASSIF_OBJECT_INDEX_DIGITS, MAX_MASSIF_INDEX, parseV2StorageObjectPath, v2CheckpointObjectKey, v2MassifObjectKey, } from "./massifs/v2storagepaths.js";
16
16
  // Massif blob node access for MMR proof building (plan-2607-15 §4)
17
+ export { massifIndexFromLeafIndex } from "./massifs/massifindex.js";
17
18
  export { openMassifNodeStore } from "./massifs/nodestore.js";
18
19
  // Content-hash leaf lookup over the massif index region (FOR-373)
19
20
  export { openMassifLeafIndex, MissingIndexError } from "./massifs/leafindex.js";
@@ -1 +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"}
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,CAYT"}
@@ -13,8 +13,9 @@
13
13
  export function isMassifFull(massifHeight, logEntries) {
14
14
  // Convert 1-based height to 0-based height index
15
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);
16
+ // Expected number of leaves for a full massif: f = 2^g, in bigint (a JS
17
+ // number `1 << g` wraps at g = 32).
18
+ const expectedLeaves = 1n << BigInt(heightIndex);
18
19
  // Actual number of leaves: f = (n + 1) / 2
19
20
  const actualLeaves = (logEntries + 1n) >> 1n;
20
21
  return actualLeaves >= expectedLeaves;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Which massif holds a leaf. A massif of one-based height h holds
3
+ * 2^(h-1) leaves; see {@link leafCountForMassifHeight} and the
4
+ * go-merklelog notation in
5
+ * [mmr-math-cheatsheet.md](https://github.com/forestrie/go-merklelog/blob/main/mmr-math-cheatsheet.md).
6
+ * Mirrors go-merklelog `massifs/massifindex.go` MassifIndexFromLeafIndex,
7
+ * which arbor's ranger uses when it commits massifs.
8
+ */
9
+ /**
10
+ * Returns the zero-based index of the massif that holds the leaf at
11
+ * `leafIndex` (zero-based, counting leaves only).
12
+ *
13
+ * @param massifHeight - One-based massif height (h >= 1)
14
+ * @throws RangeError when massifHeight is 0, which holds no leaves
15
+ */
16
+ export declare function massifIndexFromLeafIndex(massifHeight: number, leafIndex: bigint | number): bigint;
17
+ //# sourceMappingURL=massifindex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"massifindex.d.ts","sourceRoot":"","sources":["../../src/massifs/massifindex.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAAG,MAAM,GACzB,MAAM,CAMR"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Which massif holds a leaf. A massif of one-based height h holds
3
+ * 2^(h-1) leaves; see {@link leafCountForMassifHeight} and the
4
+ * go-merklelog notation in
5
+ * [mmr-math-cheatsheet.md](https://github.com/forestrie/go-merklelog/blob/main/mmr-math-cheatsheet.md).
6
+ * Mirrors go-merklelog `massifs/massifindex.go` MassifIndexFromLeafIndex,
7
+ * which arbor's ranger uses when it commits massifs.
8
+ */
9
+ import { leafCountForMassifHeight } from "./indexformat.js";
10
+ /**
11
+ * Returns the zero-based index of the massif that holds the leaf at
12
+ * `leafIndex` (zero-based, counting leaves only).
13
+ *
14
+ * @param massifHeight - One-based massif height (h >= 1)
15
+ * @throws RangeError when massifHeight is 0, which holds no leaves
16
+ */
17
+ export function massifIndexFromLeafIndex(massifHeight, leafIndex) {
18
+ const leavesPerMassif = leafCountForMassifHeight(massifHeight);
19
+ if (leavesPerMassif === 0n) {
20
+ throw new RangeError("massifHeight must be at least 1");
21
+ }
22
+ return BigInt(leafIndex) / leavesPerMassif;
23
+ }
@@ -11,5 +11,5 @@
11
11
  * @param blobSize - Size of the massif blob in bytes
12
12
  * @returns The last MMR index in the massif
13
13
  */
14
- export declare function computeLastMMRIndex(massifHeight: number, massifIndex: number, blobSize: number): bigint;
14
+ export declare function computeLastMMRIndex(massifHeight: number, massifIndex: number | bigint, blobSize: number): bigint;
15
15
  //# sourceMappingURL=mmrindex.d.ts.map
@@ -1 +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"}
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,GAAG,MAAM,EAC5B,QAAQ,EAAE,MAAM,GACf,MAAM,CAUR"}
@@ -21,7 +21,7 @@ export declare function leafMinusSpurSum(leafIndex: bigint): bigint;
21
21
  *
22
22
  * Translated from go-merklelog/massifs/massifstart.go MassifFirstLeaf
23
23
  */
24
- export declare function massifFirstLeaf(massifHeight: number, massifIndex: number): bigint;
24
+ export declare function massifFirstLeaf(massifHeight: number, massifIndex: number | bigint): bigint;
25
25
  /**
26
26
  * Returns the node index for the leaf e
27
27
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mmr/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQ1D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,MAAM,CAYR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAalD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mmr/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQ1D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B,MAAM,CAaR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAalD"}
package/dist/mmr/index.js CHANGED
@@ -30,8 +30,9 @@ export function leafMinusSpurSum(leafIndex) {
30
30
  * Translated from go-merklelog/massifs/massifstart.go MassifFirstLeaf
31
31
  */
32
32
  export function massifFirstLeaf(massifHeight, massifIndex) {
33
- // The number of nodes 'm' in a massif is: m = (1 << h) - 1
34
- const m = BigInt((1 << massifHeight) - 1);
33
+ // The number of nodes 'm' in a massif is: m = (1 << h) - 1. BigInt shift:
34
+ // a JS number `1 << h` is negative at h=31 and wraps at h=32.
35
+ const m = (1n << BigInt(massifHeight)) - 1n;
35
36
  // The number of leaves 'f' in every massif: f = (m + 1) / 2
36
37
  const f = (m + 1n) >> 1n;
37
38
  // The first leaf index is then: leafIndex = f * massifIndex
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forestrie/merklelog",
3
- "version": "0.6.0",
3
+ "version": "0.7.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "MMR (merkle mountain range) proofs and massif storage format for Forestrie transparency logs",
package/src/index.ts CHANGED
@@ -53,6 +53,7 @@ export {
53
53
  } from "./massifs/v2storagepaths.js";
54
54
 
55
55
  // Massif blob node access for MMR proof building (plan-2607-15 §4)
56
+ export { massifIndexFromLeafIndex } from "./massifs/massifindex.js";
56
57
  export { openMassifNodeStore } from "./massifs/nodestore.js";
57
58
  export type { MassifNodeStore } from "./massifs/nodestore.js";
58
59
 
@@ -18,8 +18,9 @@ export function isMassifFull(
18
18
  // Convert 1-based height to 0-based height index
19
19
  const heightIndex = massifHeight - 1;
20
20
 
21
- // Expected number of leaves for a full massif: f = 2^g = 1 << heightIndex
22
- const expectedLeaves = BigInt(1 << heightIndex);
21
+ // Expected number of leaves for a full massif: f = 2^g, in bigint (a JS
22
+ // number `1 << g` wraps at g = 32).
23
+ const expectedLeaves = 1n << BigInt(heightIndex);
23
24
 
24
25
  // Actual number of leaves: f = (n + 1) / 2
25
26
  const actualLeaves = (logEntries + 1n) >> 1n;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Which massif holds a leaf. A massif of one-based height h holds
3
+ * 2^(h-1) leaves; see {@link leafCountForMassifHeight} and the
4
+ * go-merklelog notation in
5
+ * [mmr-math-cheatsheet.md](https://github.com/forestrie/go-merklelog/blob/main/mmr-math-cheatsheet.md).
6
+ * Mirrors go-merklelog `massifs/massifindex.go` MassifIndexFromLeafIndex,
7
+ * which arbor's ranger uses when it commits massifs.
8
+ */
9
+
10
+ import { leafCountForMassifHeight } from "./indexformat.js";
11
+
12
+ /**
13
+ * Returns the zero-based index of the massif that holds the leaf at
14
+ * `leafIndex` (zero-based, counting leaves only).
15
+ *
16
+ * @param massifHeight - One-based massif height (h >= 1)
17
+ * @throws RangeError when massifHeight is 0, which holds no leaves
18
+ */
19
+ export function massifIndexFromLeafIndex(
20
+ massifHeight: number,
21
+ leafIndex: bigint | number,
22
+ ): bigint {
23
+ const leavesPerMassif = leafCountForMassifHeight(massifHeight);
24
+ if (leavesPerMassif === 0n) {
25
+ throw new RangeError("massifHeight must be at least 1");
26
+ }
27
+ return BigInt(leafIndex) / leavesPerMassif;
28
+ }
@@ -17,7 +17,7 @@ import { massifFirstLeaf } from "../mmr/index.js";
17
17
  */
18
18
  export function computeLastMMRIndex(
19
19
  massifHeight: number,
20
- massifIndex: number,
20
+ massifIndex: number | bigint,
21
21
  blobSize: number,
22
22
  ): bigint {
23
23
  // Calculate number of log entries (nodes) in the blob
package/src/mmr/index.ts CHANGED
@@ -33,10 +33,11 @@ export function leafMinusSpurSum(leafIndex: bigint): bigint {
33
33
  */
34
34
  export function massifFirstLeaf(
35
35
  massifHeight: number,
36
- massifIndex: number,
36
+ massifIndex: number | bigint,
37
37
  ): bigint {
38
- // The number of nodes 'm' in a massif is: m = (1 << h) - 1
39
- const m = BigInt((1 << massifHeight) - 1);
38
+ // The number of nodes 'm' in a massif is: m = (1 << h) - 1. BigInt shift:
39
+ // a JS number `1 << h` is negative at h=31 and wraps at h=32.
40
+ const m = (1n << BigInt(massifHeight)) - 1n;
40
41
 
41
42
  // The number of leaves 'f' in every massif: f = (m + 1) / 2
42
43
  const f = (m + 1n) >> 1n;