@optimystic/db-p2p-storage-rn 0.24.2 → 0.25.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 CHANGED
@@ -6,7 +6,7 @@ on-device LevelDB. Provides:
6
6
 
7
7
  - **`LevelDBRawStorage`** — implements `IRawStorage` so an RN node persists
8
8
  block metadata, revisions, pending transactions, committed transactions,
9
- and materialized blocks.
9
+ commit proofs, and materialized blocks.
10
10
  - **`LevelDBKVStore`** — implements `IKVStore` for the persistent
11
11
  transaction state used to recover crashed two-phase commits.
12
12
  - **`loadOrCreateRNPeerKey`** — generates an Ed25519 libp2p private key on
@@ -13,6 +13,7 @@
13
13
  * - revisions: rev (8-byte big-endian unsigned via DataView.setBigUint64)
14
14
  * - pending: actionId UTF-8 (terminal)
15
15
  * - transactions: actionId UTF-8 (terminal)
16
+ * - proofs: rev (8-byte big-endian unsigned, same as revisions)
16
17
  * - materialized: actionId UTF-8 (terminal)
17
18
  *
18
19
  * `kv` and `identity` keys are flat — no `blockId` envelope — under their
@@ -27,6 +28,7 @@ export declare const TAG_REVISIONS = 2;
27
28
  export declare const TAG_PENDING = 3;
28
29
  export declare const TAG_TRANSACTIONS = 4;
29
30
  export declare const TAG_MATERIALIZED = 5;
31
+ export declare const TAG_PROOFS = 6;
30
32
  export declare const TAG_KV = 16;
31
33
  export declare const TAG_IDENTITY = 32;
32
34
  export declare function metadataKey(blockId: string): Uint8Array;
@@ -49,6 +51,12 @@ export declare function revisionKey(blockId: string, rev: number): Uint8Array;
49
51
  export declare function revisionFromKey(key: Uint8Array): number;
50
52
  export declare function pendingKey(blockId: string, actionId: string): Uint8Array;
51
53
  export declare function transactionKey(blockId: string, actionId: string): Uint8Array;
54
+ /**
55
+ * Proofs are keyed by `(blockId, rev)` with the SAME 8-byte big-endian rev suffix as
56
+ * `revisionKey`, under their own tag — deliberately not the action keyspace, since an
57
+ * action id is chosen by whoever originates a write (see `RawStoreDriver.getProof`).
58
+ */
59
+ export declare function proofKey(blockId: string, rev: number): Uint8Array;
52
60
  export declare function materializedKey(blockId: string, actionId: string): Uint8Array;
53
61
  /** Returns the inclusive lower / exclusive upper range covering every key for `(tag, blockId, *)`. */
54
62
  export declare function blockEnvelopeRange(tag: number, blockId: string): {
@@ -1 +1 @@
1
- {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,eAAO,MAAM,YAAY,IAAO,CAAC;AACjC,eAAO,MAAM,aAAa,IAAO,CAAC;AAClC,eAAO,MAAM,WAAW,IAAO,CAAC;AAChC,eAAO,MAAM,gBAAgB,IAAO,CAAC;AACrC,eAAO,MAAM,gBAAgB,IAAO,CAAC;AACrC,eAAO,MAAM,MAAM,KAAO,CAAC;AAC3B,eAAO,MAAM,YAAY,KAAO,CAAC;AA0BjC,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAEvD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,IAAI;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,UAAU,CAAA;CAAE,CAEnE;AAED,4EAA4E;AAC5E,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAI9D;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAMpE;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAGvD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAExE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAE5E;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAE7E;AAED,sGAAsG;AACtG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,UAAU,CAAA;CAAE,CAapG;AAED,+FAA+F;AAC/F,wBAAgB,eAAe,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAIxE;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAE7C;AAED,wGAAwG;AACxG,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,UAAU,CAAA;CAAE,CAcjF;AAED,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAErD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAEvD"}
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,eAAO,MAAM,YAAY,IAAO,CAAC;AACjC,eAAO,MAAM,aAAa,IAAO,CAAC;AAClC,eAAO,MAAM,WAAW,IAAO,CAAC;AAChC,eAAO,MAAM,gBAAgB,IAAO,CAAC;AACrC,eAAO,MAAM,gBAAgB,IAAO,CAAC;AACrC,eAAO,MAAM,UAAU,IAAO,CAAC;AAC/B,eAAO,MAAM,MAAM,KAAO,CAAC;AAC3B,eAAO,MAAM,YAAY,KAAO,CAAC;AA0BjC,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAEvD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,IAAI;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,UAAU,CAAA;CAAE,CAEnE;AAED,4EAA4E;AAC5E,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAI9D;AAeD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAEpE;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAGvD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAExE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAEjE;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAE7E;AAED,sGAAsG;AACtG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,UAAU,CAAA;CAAE,CAapG;AAED,+FAA+F;AAC/F,wBAAgB,eAAe,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAIxE;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAE7C;AAED,wGAAwG;AACxG,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,UAAU,CAAA;CAAE,CAcjF;AAED,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAErD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAEvD"}
package/dist/src/keys.js CHANGED
@@ -13,6 +13,7 @@
13
13
  * - revisions: rev (8-byte big-endian unsigned via DataView.setBigUint64)
14
14
  * - pending: actionId UTF-8 (terminal)
15
15
  * - transactions: actionId UTF-8 (terminal)
16
+ * - proofs: rev (8-byte big-endian unsigned, same as revisions)
16
17
  * - materialized: actionId UTF-8 (terminal)
17
18
  *
18
19
  * `kv` and `identity` keys are flat — no `blockId` envelope — under their
@@ -27,6 +28,7 @@ export const TAG_REVISIONS = 0x02;
27
28
  export const TAG_PENDING = 0x03;
28
29
  export const TAG_TRANSACTIONS = 0x04;
29
30
  export const TAG_MATERIALIZED = 0x05;
31
+ export const TAG_PROOFS = 0x06;
30
32
  export const TAG_KV = 0x10;
31
33
  export const TAG_IDENTITY = 0x20;
32
34
  const textEncoder = new TextEncoder();
@@ -71,13 +73,21 @@ export function blockIdFromMetadataKey(key) {
71
73
  const blockIdLen = view.getUint32(1, false);
72
74
  return textDecoder.decode(key.subarray(5, 5 + blockIdLen));
73
75
  }
74
- export function revisionKey(blockId, rev) {
75
- const envelope = encodeBlockEnvelope(TAG_REVISIONS, blockId);
76
+ /**
77
+ * `tag || len(blockId) || blockId || rev (8 BE)`. The fixed-width big-endian suffix is
78
+ * what makes a rev-keyed store scan in numeric order; `revisionFromKey` decodes it back.
79
+ * Shared by every rev-keyed store so their encodings cannot drift apart.
80
+ */
81
+ function revScopedKey(tag, blockId, rev) {
82
+ const envelope = encodeBlockEnvelope(tag, blockId);
76
83
  const out = new Uint8Array(envelope.length + 8);
77
84
  out.set(envelope, 0);
78
85
  new DataView(out.buffer, out.byteOffset).setBigUint64(envelope.length, BigInt(rev), false);
79
86
  return out;
80
87
  }
88
+ export function revisionKey(blockId, rev) {
89
+ return revScopedKey(TAG_REVISIONS, blockId, rev);
90
+ }
81
91
  /** Decode the trailing 8-byte big-endian rev from a `revisionKey`-encoded key. */
82
92
  export function revisionFromKey(key) {
83
93
  const view = new DataView(key.buffer, key.byteOffset, key.byteLength);
@@ -89,6 +99,14 @@ export function pendingKey(blockId, actionId) {
89
99
  export function transactionKey(blockId, actionId) {
90
100
  return concat(encodeBlockEnvelope(TAG_TRANSACTIONS, blockId), textEncoder.encode(actionId));
91
101
  }
102
+ /**
103
+ * Proofs are keyed by `(blockId, rev)` with the SAME 8-byte big-endian rev suffix as
104
+ * `revisionKey`, under their own tag — deliberately not the action keyspace, since an
105
+ * action id is chosen by whoever originates a write (see `RawStoreDriver.getProof`).
106
+ */
107
+ export function proofKey(blockId, rev) {
108
+ return revScopedKey(TAG_PROOFS, blockId, rev);
109
+ }
92
110
  export function materializedKey(blockId, actionId) {
93
111
  return concat(encodeBlockEnvelope(TAG_MATERIALIZED, blockId), textEncoder.encode(actionId));
94
112
  }
@@ -1 +1 @@
1
- {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/keys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/keys.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import type { ActionId, BlockId } from '@optimystic/db-core';
2
- import { KvRawStorage, type RawStoreDriver } from '@optimystic/db-p2p';
2
+ import { KvRawStorage, type RawStoreDriver, type StoreIdentity } from '@optimystic/db-p2p';
3
3
  import { type LevelDBLike } from './leveldb-like.js';
4
4
  /**
5
- * LevelDB {@link RawStoreDriver}: the five logical block-storage stores mapped
5
+ * LevelDB {@link RawStoreDriver}: the six logical block-storage stores mapped
6
6
  * into a single ordered byte keyspace, partitioned by a leading tag byte (see
7
7
  * `./keys.ts`). LevelDB is already one ordered byte-keyspace, so this driver is
8
8
  * mostly key encoding — the tag-prefixed byte scheme in `keys.ts` stays in this
@@ -17,7 +17,9 @@ import { type LevelDBLike } from './leveldb-like.js';
17
17
  */
18
18
  export declare class LevelDBStoreDriver implements RawStoreDriver {
19
19
  private readonly db;
20
+ private readonly identity;
20
21
  constructor(db: LevelDBLike);
22
+ storeIdentity(): StoreIdentity;
21
23
  getMetadata(blockId: BlockId): Promise<Uint8Array | undefined>;
22
24
  putMetadata(blockId: BlockId, value: Uint8Array): Promise<void>;
23
25
  getRevision(blockId: BlockId, rev: number): Promise<Uint8Array | undefined>;
@@ -29,6 +31,8 @@ export declare class LevelDBStoreDriver implements RawStoreDriver {
29
31
  listPendingActionIds(blockId: BlockId): AsyncIterable<ActionId>;
30
32
  getTransaction(blockId: BlockId, actionId: ActionId): Promise<Uint8Array | undefined>;
31
33
  putTransaction(blockId: BlockId, actionId: ActionId, value: Uint8Array): Promise<void>;
34
+ getProof(blockId: BlockId, rev: number): Promise<Uint8Array | undefined>;
35
+ putProof(blockId: BlockId, rev: number, value: Uint8Array): Promise<void>;
32
36
  getMaterialized(blockId: BlockId, actionId: ActionId): Promise<Uint8Array | undefined>;
33
37
  putMaterialized(blockId: BlockId, actionId: ActionId, value: Uint8Array): Promise<void>;
34
38
  deleteMaterialized(blockId: BlockId, actionId: ActionId): Promise<void>;
@@ -51,6 +55,7 @@ export declare class LevelDBStoreDriver implements RawStoreDriver {
51
55
  export declare class LevelDBRawStorage extends KvRawStorage {
52
56
  listBlockIds: () => AsyncIterable<BlockId>;
53
57
  getApproximateBytesUsed: () => Promise<number>;
58
+ getStoreIdentity: () => StoreIdentity;
54
59
  constructor(db: LevelDBLike);
55
60
  }
56
61
  //# sourceMappingURL=leveldb-storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"leveldb-storage.d.ts","sourceRoot":"","sources":["../../src/leveldb-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAS,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAkB5D;;;;;;;;;;;;;GAaG;AACH,qBAAa,kBAAmB,YAAW,cAAc;IAC5C,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,WAAW;IAItC,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAI9D,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/D,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAI3E,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3E,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,aAAa,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAgBhH,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIjF,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlF,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC;IAWhE,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIrF,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtF,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAItF,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvF,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB3D,YAAY,IAAI,aAAa,CAAC,OAAO,CAAC;IAgBvC,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;CAyB7C;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,iBAAkB,SAAQ,YAAY;IAC1C,YAAY,EAAE,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;IAC3C,uBAAuB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;gBAE3C,EAAE,EAAE,WAAW;CAG3B"}
1
+ {"version":3,"file":"leveldb-storage.d.ts","sourceRoot":"","sources":["../../src/leveldb-storage.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,10 @@
1
- import { KvRawStorage } from '@optimystic/db-p2p';
1
+ import { KvRawStorage, identityForHandle } from '@optimystic/db-p2p';
2
2
  import { drain } from './leveldb-like.js';
3
- import { TAG_PENDING, actionIdFromKey, blockEnvelopeRange, blockIdFromMetadataKey, materializedKey, metadataKey, metadataRange, pendingKey, revisionFromKey, revisionKey, transactionKey, } from './keys.js';
3
+ import { TAG_PENDING, actionIdFromKey, blockEnvelopeRange, blockIdFromMetadataKey, materializedKey, metadataKey, metadataRange, pendingKey, proofKey, revisionFromKey, revisionKey, transactionKey, } from './keys.js';
4
4
  import { createLogger } from './logger.js';
5
5
  const log = createLogger('storage:leveldb');
6
6
  /**
7
- * LevelDB {@link RawStoreDriver}: the five logical block-storage stores mapped
7
+ * LevelDB {@link RawStoreDriver}: the six logical block-storage stores mapped
8
8
  * into a single ordered byte keyspace, partitioned by a leading tag byte (see
9
9
  * `./keys.ts`). LevelDB is already one ordered byte-keyspace, so this driver is
10
10
  * mostly key encoding — the tag-prefixed byte scheme in `keys.ts` stays in this
@@ -19,8 +19,17 @@ const log = createLogger('storage:leveldb');
19
19
  */
20
20
  export class LevelDBStoreDriver {
21
21
  db;
22
+ // NOTE: identity is the HANDLE object, so two handles opened over the same LevelDB PATH read
23
+ // as two identities. Resolving that would mean naming the underlying on-disk path, which
24
+ // `LevelDBLike` does not expose. The package opener (`rn-opener.ts`) hands out one handle per
25
+ // path in practice, so this is the reachable case, not the complete one.
26
+ identity;
22
27
  constructor(db) {
23
28
  this.db = db;
29
+ this.identity = identityForHandle('leveldb-handle', db);
30
+ }
31
+ storeIdentity() {
32
+ return this.identity;
24
33
  }
25
34
  // --- metadata ---
26
35
  async getMetadata(blockId) {
@@ -74,6 +83,13 @@ export class LevelDBStoreDriver {
74
83
  async putTransaction(blockId, actionId, value) {
75
84
  await this.db.put(transactionKey(blockId, actionId), value);
76
85
  }
86
+ // --- proofs (own tag byte; no delete — see RawStoreDriver.getProof) ---
87
+ async getProof(blockId, rev) {
88
+ return this.db.get(proofKey(blockId, rev));
89
+ }
90
+ async putProof(blockId, rev, value) {
91
+ await this.db.put(proofKey(blockId, rev), value);
92
+ }
77
93
  // --- materialized ---
78
94
  async getMaterialized(blockId, actionId) {
79
95
  return this.db.get(materializedKey(blockId, actionId));
@@ -1 +1 @@
1
- {"version":3,"file":"leveldb-storage.js","sourceRoot":"","sources":["../../src/leveldb-storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"leveldb-storage.js","sourceRoot":"","sources":["../../src/leveldb-storage.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optimystic/db-p2p-storage-rn",
3
- "version": "0.24.2",
3
+ "version": "0.25.0",
4
4
  "type": "module",
5
5
  "description": "React Native LevelDB storage backend for @optimystic/db-p2p",
6
6
  "main": "dist/src/index.js",
@@ -54,8 +54,8 @@
54
54
  "typescript": "^5.9.3"
55
55
  },
56
56
  "dependencies": {
57
- "@optimystic/db-core": "^0.24.2",
58
- "@optimystic/db-p2p": "^0.24.2",
57
+ "@optimystic/db-core": "^0.25.0",
58
+ "@optimystic/db-p2p": "^0.25.0",
59
59
  "debug": "^4.4.3"
60
60
  },
61
61
  "peerDependencies": {
package/src/keys.ts CHANGED
@@ -13,6 +13,7 @@
13
13
  * - revisions: rev (8-byte big-endian unsigned via DataView.setBigUint64)
14
14
  * - pending: actionId UTF-8 (terminal)
15
15
  * - transactions: actionId UTF-8 (terminal)
16
+ * - proofs: rev (8-byte big-endian unsigned, same as revisions)
16
17
  * - materialized: actionId UTF-8 (terminal)
17
18
  *
18
19
  * `kv` and `identity` keys are flat — no `blockId` envelope — under their
@@ -28,6 +29,7 @@ export const TAG_REVISIONS = 0x02;
28
29
  export const TAG_PENDING = 0x03;
29
30
  export const TAG_TRANSACTIONS = 0x04;
30
31
  export const TAG_MATERIALIZED = 0x05;
32
+ export const TAG_PROOFS = 0x06;
31
33
  export const TAG_KV = 0x10;
32
34
  export const TAG_IDENTITY = 0x20;
33
35
 
@@ -78,14 +80,23 @@ export function blockIdFromMetadataKey(key: Uint8Array): string {
78
80
  return textDecoder.decode(key.subarray(5, 5 + blockIdLen));
79
81
  }
80
82
 
81
- export function revisionKey(blockId: string, rev: number): Uint8Array {
82
- const envelope = encodeBlockEnvelope(TAG_REVISIONS, blockId);
83
+ /**
84
+ * `tag || len(blockId) || blockId || rev (8 BE)`. The fixed-width big-endian suffix is
85
+ * what makes a rev-keyed store scan in numeric order; `revisionFromKey` decodes it back.
86
+ * Shared by every rev-keyed store so their encodings cannot drift apart.
87
+ */
88
+ function revScopedKey(tag: number, blockId: string, rev: number): Uint8Array {
89
+ const envelope = encodeBlockEnvelope(tag, blockId);
83
90
  const out = new Uint8Array(envelope.length + 8);
84
91
  out.set(envelope, 0);
85
92
  new DataView(out.buffer, out.byteOffset).setBigUint64(envelope.length, BigInt(rev), false);
86
93
  return out;
87
94
  }
88
95
 
96
+ export function revisionKey(blockId: string, rev: number): Uint8Array {
97
+ return revScopedKey(TAG_REVISIONS, blockId, rev);
98
+ }
99
+
89
100
  /** Decode the trailing 8-byte big-endian rev from a `revisionKey`-encoded key. */
90
101
  export function revisionFromKey(key: Uint8Array): number {
91
102
  const view = new DataView(key.buffer, key.byteOffset, key.byteLength);
@@ -100,6 +111,15 @@ export function transactionKey(blockId: string, actionId: string): Uint8Array {
100
111
  return concat(encodeBlockEnvelope(TAG_TRANSACTIONS, blockId), textEncoder.encode(actionId));
101
112
  }
102
113
 
114
+ /**
115
+ * Proofs are keyed by `(blockId, rev)` with the SAME 8-byte big-endian rev suffix as
116
+ * `revisionKey`, under their own tag — deliberately not the action keyspace, since an
117
+ * action id is chosen by whoever originates a write (see `RawStoreDriver.getProof`).
118
+ */
119
+ export function proofKey(blockId: string, rev: number): Uint8Array {
120
+ return revScopedKey(TAG_PROOFS, blockId, rev);
121
+ }
122
+
103
123
  export function materializedKey(blockId: string, actionId: string): Uint8Array {
104
124
  return concat(encodeBlockEnvelope(TAG_MATERIALIZED, blockId), textEncoder.encode(actionId));
105
125
  }
@@ -1,203 +1,227 @@
1
- import type { ActionId, BlockId } from '@optimystic/db-core';
2
- import { KvRawStorage, type RawStoreDriver } from '@optimystic/db-p2p';
3
- import { drain, type LevelDBLike } from './leveldb-like.js';
4
- import {
5
- TAG_PENDING,
6
- actionIdFromKey,
7
- blockEnvelopeRange,
8
- blockIdFromMetadataKey,
9
- materializedKey,
10
- metadataKey,
11
- metadataRange,
12
- pendingKey,
13
- revisionFromKey,
14
- revisionKey,
15
- transactionKey,
16
- } from './keys.js';
17
- import { createLogger } from './logger.js';
18
-
19
- const log = createLogger('storage:leveldb');
20
-
21
- /**
22
- * LevelDB {@link RawStoreDriver}: the five logical block-storage stores mapped
23
- * into a single ordered byte keyspace, partitioned by a leading tag byte (see
24
- * `./keys.ts`). LevelDB is already one ordered byte-keyspace, so this driver is
25
- * mostly key encoding — the tag-prefixed byte scheme in `keys.ts` stays in this
26
- * package; the kernel deals in logical keys.
27
- *
28
- * `KvRawStorage` now owns all JSON/UTF-8 serialization, so this driver only ever
29
- * reads/writes raw `Uint8Array` values — no `TextEncoder`/`TextDecoder` for
30
- * values, and no `JSON.parse`/`stringify`. A value round-trips as the exact bytes
31
- * the kernel wrote. Everything LevelDB-specific stays here: the tag-range scans
32
- * (drained snapshot-first before yielding, so a native iterator never straddles a
33
- * consumer's `await`), and the single `WriteBatch` that makes `promote` atomic.
34
- */
35
- export class LevelDBStoreDriver implements RawStoreDriver {
36
- constructor(private readonly db: LevelDBLike) {}
37
-
38
- // --- metadata ---
39
-
40
- async getMetadata(blockId: BlockId): Promise<Uint8Array | undefined> {
41
- return this.db.get(metadataKey(blockId));
42
- }
43
-
44
- async putMetadata(blockId: BlockId, value: Uint8Array): Promise<void> {
45
- await this.db.put(metadataKey(blockId), value);
46
- }
47
-
48
- // --- revisions ---
49
-
50
- async getRevision(blockId: BlockId, rev: number): Promise<Uint8Array | undefined> {
51
- return this.db.get(revisionKey(blockId, rev));
52
- }
53
-
54
- async putRevision(blockId: BlockId, rev: number, value: Uint8Array): Promise<void> {
55
- await this.db.put(revisionKey(blockId, rev), value);
56
- }
57
-
58
- async *rangeRevisions(blockId: BlockId, lo: number, hi: number, reverse: boolean): AsyncIterable<[number, Uint8Array]> {
59
- // Revs are encoded 8-byte big-endian (`revisionKey`), so byte order == numeric
60
- // order and `revisionKey(blockId, hi)` is exactly the inclusive upper bound;
61
- // LevelDB's upper bound is exclusive (`lt`), so use `lt = revisionKey(hi + 1)`.
62
- const gte = revisionKey(blockId, lo);
63
- const lt = revisionKey(blockId, hi + 1);
64
- // Drain before yielding — a native LevelDB iterator must not stay open across
65
- // the consumer's awaits (the kernel's drain-before-yield contract).
66
- const entries = await drain(this.db.iterator({ gte, lt, reverse }));
67
- for (const [key, value] of entries) {
68
- yield [revisionFromKey(key), value];
69
- }
70
- }
71
-
72
- // --- pending ---
73
-
74
- async getPending(blockId: BlockId, actionId: ActionId): Promise<Uint8Array | undefined> {
75
- return this.db.get(pendingKey(blockId, actionId));
76
- }
77
-
78
- async putPending(blockId: BlockId, actionId: ActionId, value: Uint8Array): Promise<void> {
79
- await this.db.put(pendingKey(blockId, actionId), value);
80
- }
81
-
82
- async deletePending(blockId: BlockId, actionId: ActionId): Promise<void> {
83
- await this.db.delete(pendingKey(blockId, actionId));
84
- }
85
-
86
- async *listPendingActionIds(blockId: BlockId): AsyncIterable<ActionId> {
87
- const range = blockEnvelopeRange(TAG_PENDING, blockId);
88
- // Drain before yielding, same rationale as rangeRevisions.
89
- const entries = await drain(this.db.iterator({ gte: range.gte, lt: range.lt, keys: true }));
90
- for (const [key] of entries) {
91
- yield actionIdFromKey(key, blockId) as ActionId;
92
- }
93
- }
94
-
95
- // --- transactions ---
96
-
97
- async getTransaction(blockId: BlockId, actionId: ActionId): Promise<Uint8Array | undefined> {
98
- return this.db.get(transactionKey(blockId, actionId));
99
- }
100
-
101
- async putTransaction(blockId: BlockId, actionId: ActionId, value: Uint8Array): Promise<void> {
102
- await this.db.put(transactionKey(blockId, actionId), value);
103
- }
104
-
105
- // --- materialized ---
106
-
107
- async getMaterialized(blockId: BlockId, actionId: ActionId): Promise<Uint8Array | undefined> {
108
- return this.db.get(materializedKey(blockId, actionId));
109
- }
110
-
111
- async putMaterialized(blockId: BlockId, actionId: ActionId, value: Uint8Array): Promise<void> {
112
- await this.db.put(materializedKey(blockId, actionId), value);
113
- }
114
-
115
- // The kernel owns the put-or-delete branch of `saveMaterializedBlock`, so the
116
- // driver exposes delete as a separate op.
117
- async deleteMaterialized(blockId: BlockId, actionId: ActionId): Promise<void> {
118
- await this.db.delete(materializedKey(blockId, actionId));
119
- }
120
-
121
- // --- promote (the only cross-key atomic op) ---
122
-
123
- async promote(blockId: BlockId, actionId: ActionId): Promise<void> {
124
- const pKey = pendingKey(blockId, actionId);
125
- const value = await this.db.get(pKey);
126
- if (!value) {
127
- throw new Error(`Pending action ${actionId} not found for block ${blockId}`);
128
- }
129
- // The single `WriteBatch` IS the atomic move: a crash leaves either the
130
- // pending or the committed entry, never both/neither.
131
- const tKey = transactionKey(blockId, actionId);
132
- await this.db
133
- .batch()
134
- .put(tKey, value)
135
- .delete(pKey)
136
- .write();
137
- }
138
-
139
- // --- optional passthroughs ---
140
-
141
- async *listBlockIds(): AsyncIterable<BlockId> {
142
- // Scan the whole TAG_METADATA keyspace; each metadata key is one distinct
143
- // block id (empty suffix). keys:true skips values — we only need the ids.
144
- // Drained before yielding (same discipline as the range scans): a native
145
- // iterator must not stay open across consumer awaits.
146
- const range = metadataRange();
147
- const entries = await drain(this.db.iterator({ gte: range.gte, lt: range.lt, keys: true }));
148
- for (const [key] of entries) {
149
- yield blockIdFromMetadataKey(key) as BlockId;
150
- }
151
- }
152
-
153
- // NOTE: full-scan byte sum — O(total bytes) per call. Fine as an advisory
154
- // StorageMonitor input at current sizes; if a StorageMonitor ever polls this
155
- // on a large db, replace with the kernel's incremental write-path counter
156
- // (see the seam NOTE in kv-raw-storage.ts's saveMetadata).
157
- async approximateBytesUsed(): Promise<number> {
158
- try {
159
- let total = 0;
160
- const iter = this.db.iterator();
161
- try {
162
- while (true) {
163
- const entry = await iter.next();
164
- if (!entry) break;
165
- total += entry[0].byteLength + entry[1].byteLength;
166
- }
167
- } finally {
168
- await iter.close();
169
- }
170
- return total;
171
- } catch (err) {
172
- log('approximateBytesUsed iterator failed: %o', err);
173
- return 0;
174
- }
175
- }
176
-
177
- // NOTE: intentionally NO close(). The `LevelDBLike` handle is shared with
178
- // `LevelDBKVStore` and `loadOrCreateRNPeerKey` (one db per RN peer — see the
179
- // README usage), so the driver must not own its lifecycle; closing it here
180
- // would break the other two. Same rationale as the IndexedDB driver. The
181
- // kernel never wires the optional close() regardless.
182
- }
183
-
184
- /**
185
- * LevelDB-backed {@link IRawStorage} for React Native peers, now a thin shell
186
- * over the shared {@link KvRawStorage} kernel driven by a {@link LevelDBStoreDriver}.
187
- * The public name/constructor (`new LevelDBRawStorage(db)`) is unchanged so
188
- * existing imports keep resolving; the kernel supplies the `IRawStorage` surface
189
- * and the driver supplies LevelDB behavior.
190
- *
191
- * `listBlockIds`/`getApproximateBytesUsed` are re-declared here as always-present
192
- * (the LevelDB driver always implements them, so the kernel constructor always
193
- * wires them) — the base declares them optional, but every RN consumer relies on
194
- * them.
195
- */
196
- export class LevelDBRawStorage extends KvRawStorage {
197
- declare listBlockIds: () => AsyncIterable<BlockId>;
198
- declare getApproximateBytesUsed: () => Promise<number>;
199
-
200
- constructor(db: LevelDBLike) {
201
- super(new LevelDBStoreDriver(db));
202
- }
203
- }
1
+ import type { ActionId, BlockId } from '@optimystic/db-core';
2
+ import { KvRawStorage, identityForHandle, type RawStoreDriver, type StoreIdentity } from '@optimystic/db-p2p';
3
+ import { drain, type LevelDBLike } from './leveldb-like.js';
4
+ import {
5
+ TAG_PENDING,
6
+ actionIdFromKey,
7
+ blockEnvelopeRange,
8
+ blockIdFromMetadataKey,
9
+ materializedKey,
10
+ metadataKey,
11
+ metadataRange,
12
+ pendingKey,
13
+ proofKey,
14
+ revisionFromKey,
15
+ revisionKey,
16
+ transactionKey,
17
+ } from './keys.js';
18
+ import { createLogger } from './logger.js';
19
+
20
+ const log = createLogger('storage:leveldb');
21
+
22
+ /**
23
+ * LevelDB {@link RawStoreDriver}: the six logical block-storage stores mapped
24
+ * into a single ordered byte keyspace, partitioned by a leading tag byte (see
25
+ * `./keys.ts`). LevelDB is already one ordered byte-keyspace, so this driver is
26
+ * mostly key encoding — the tag-prefixed byte scheme in `keys.ts` stays in this
27
+ * package; the kernel deals in logical keys.
28
+ *
29
+ * `KvRawStorage` now owns all JSON/UTF-8 serialization, so this driver only ever
30
+ * reads/writes raw `Uint8Array` values — no `TextEncoder`/`TextDecoder` for
31
+ * values, and no `JSON.parse`/`stringify`. A value round-trips as the exact bytes
32
+ * the kernel wrote. Everything LevelDB-specific stays here: the tag-range scans
33
+ * (drained snapshot-first before yielding, so a native iterator never straddles a
34
+ * consumer's `await`), and the single `WriteBatch` that makes `promote` atomic.
35
+ */
36
+ export class LevelDBStoreDriver implements RawStoreDriver {
37
+ // NOTE: identity is the HANDLE object, so two handles opened over the same LevelDB PATH read
38
+ // as two identities. Resolving that would mean naming the underlying on-disk path, which
39
+ // `LevelDBLike` does not expose. The package opener (`rn-opener.ts`) hands out one handle per
40
+ // path in practice, so this is the reachable case, not the complete one.
41
+ private readonly identity: StoreIdentity;
42
+
43
+ constructor(private readonly db: LevelDBLike) {
44
+ this.identity = identityForHandle('leveldb-handle', db);
45
+ }
46
+
47
+ storeIdentity(): StoreIdentity {
48
+ return this.identity;
49
+ }
50
+
51
+ // --- metadata ---
52
+
53
+ async getMetadata(blockId: BlockId): Promise<Uint8Array | undefined> {
54
+ return this.db.get(metadataKey(blockId));
55
+ }
56
+
57
+ async putMetadata(blockId: BlockId, value: Uint8Array): Promise<void> {
58
+ await this.db.put(metadataKey(blockId), value);
59
+ }
60
+
61
+ // --- revisions ---
62
+
63
+ async getRevision(blockId: BlockId, rev: number): Promise<Uint8Array | undefined> {
64
+ return this.db.get(revisionKey(blockId, rev));
65
+ }
66
+
67
+ async putRevision(blockId: BlockId, rev: number, value: Uint8Array): Promise<void> {
68
+ await this.db.put(revisionKey(blockId, rev), value);
69
+ }
70
+
71
+ async *rangeRevisions(blockId: BlockId, lo: number, hi: number, reverse: boolean): AsyncIterable<[number, Uint8Array]> {
72
+ // Revs are encoded 8-byte big-endian (`revisionKey`), so byte order == numeric
73
+ // order and `revisionKey(blockId, hi)` is exactly the inclusive upper bound;
74
+ // LevelDB's upper bound is exclusive (`lt`), so use `lt = revisionKey(hi + 1)`.
75
+ const gte = revisionKey(blockId, lo);
76
+ const lt = revisionKey(blockId, hi + 1);
77
+ // Drain before yielding — a native LevelDB iterator must not stay open across
78
+ // the consumer's awaits (the kernel's drain-before-yield contract).
79
+ const entries = await drain(this.db.iterator({ gte, lt, reverse }));
80
+ for (const [key, value] of entries) {
81
+ yield [revisionFromKey(key), value];
82
+ }
83
+ }
84
+
85
+ // --- pending ---
86
+
87
+ async getPending(blockId: BlockId, actionId: ActionId): Promise<Uint8Array | undefined> {
88
+ return this.db.get(pendingKey(blockId, actionId));
89
+ }
90
+
91
+ async putPending(blockId: BlockId, actionId: ActionId, value: Uint8Array): Promise<void> {
92
+ await this.db.put(pendingKey(blockId, actionId), value);
93
+ }
94
+
95
+ async deletePending(blockId: BlockId, actionId: ActionId): Promise<void> {
96
+ await this.db.delete(pendingKey(blockId, actionId));
97
+ }
98
+
99
+ async *listPendingActionIds(blockId: BlockId): AsyncIterable<ActionId> {
100
+ const range = blockEnvelopeRange(TAG_PENDING, blockId);
101
+ // Drain before yielding, same rationale as rangeRevisions.
102
+ const entries = await drain(this.db.iterator({ gte: range.gte, lt: range.lt, keys: true }));
103
+ for (const [key] of entries) {
104
+ yield actionIdFromKey(key, blockId) as ActionId;
105
+ }
106
+ }
107
+
108
+ // --- transactions ---
109
+
110
+ async getTransaction(blockId: BlockId, actionId: ActionId): Promise<Uint8Array | undefined> {
111
+ return this.db.get(transactionKey(blockId, actionId));
112
+ }
113
+
114
+ async putTransaction(blockId: BlockId, actionId: ActionId, value: Uint8Array): Promise<void> {
115
+ await this.db.put(transactionKey(blockId, actionId), value);
116
+ }
117
+
118
+ // --- proofs (own tag byte; no delete — see RawStoreDriver.getProof) ---
119
+
120
+ async getProof(blockId: BlockId, rev: number): Promise<Uint8Array | undefined> {
121
+ return this.db.get(proofKey(blockId, rev));
122
+ }
123
+
124
+ async putProof(blockId: BlockId, rev: number, value: Uint8Array): Promise<void> {
125
+ await this.db.put(proofKey(blockId, rev), value);
126
+ }
127
+
128
+ // --- materialized ---
129
+
130
+ async getMaterialized(blockId: BlockId, actionId: ActionId): Promise<Uint8Array | undefined> {
131
+ return this.db.get(materializedKey(blockId, actionId));
132
+ }
133
+
134
+ async putMaterialized(blockId: BlockId, actionId: ActionId, value: Uint8Array): Promise<void> {
135
+ await this.db.put(materializedKey(blockId, actionId), value);
136
+ }
137
+
138
+ // The kernel owns the put-or-delete branch of `saveMaterializedBlock`, so the
139
+ // driver exposes delete as a separate op.
140
+ async deleteMaterialized(blockId: BlockId, actionId: ActionId): Promise<void> {
141
+ await this.db.delete(materializedKey(blockId, actionId));
142
+ }
143
+
144
+ // --- promote (the only cross-key atomic op) ---
145
+
146
+ async promote(blockId: BlockId, actionId: ActionId): Promise<void> {
147
+ const pKey = pendingKey(blockId, actionId);
148
+ const value = await this.db.get(pKey);
149
+ if (!value) {
150
+ throw new Error(`Pending action ${actionId} not found for block ${blockId}`);
151
+ }
152
+ // The single `WriteBatch` IS the atomic move: a crash leaves either the
153
+ // pending or the committed entry, never both/neither.
154
+ const tKey = transactionKey(blockId, actionId);
155
+ await this.db
156
+ .batch()
157
+ .put(tKey, value)
158
+ .delete(pKey)
159
+ .write();
160
+ }
161
+
162
+ // --- optional passthroughs ---
163
+
164
+ async *listBlockIds(): AsyncIterable<BlockId> {
165
+ // Scan the whole TAG_METADATA keyspace; each metadata key is one distinct
166
+ // block id (empty suffix). keys:true skips values — we only need the ids.
167
+ // Drained before yielding (same discipline as the range scans): a native
168
+ // iterator must not stay open across consumer awaits.
169
+ const range = metadataRange();
170
+ const entries = await drain(this.db.iterator({ gte: range.gte, lt: range.lt, keys: true }));
171
+ for (const [key] of entries) {
172
+ yield blockIdFromMetadataKey(key) as BlockId;
173
+ }
174
+ }
175
+
176
+ // NOTE: full-scan byte sum — O(total bytes) per call. Fine as an advisory
177
+ // StorageMonitor input at current sizes; if a StorageMonitor ever polls this
178
+ // on a large db, replace with the kernel's incremental write-path counter
179
+ // (see the seam NOTE in kv-raw-storage.ts's saveMetadata).
180
+ async approximateBytesUsed(): Promise<number> {
181
+ try {
182
+ let total = 0;
183
+ const iter = this.db.iterator();
184
+ try {
185
+ while (true) {
186
+ const entry = await iter.next();
187
+ if (!entry) break;
188
+ total += entry[0].byteLength + entry[1].byteLength;
189
+ }
190
+ } finally {
191
+ await iter.close();
192
+ }
193
+ return total;
194
+ } catch (err) {
195
+ log('approximateBytesUsed iterator failed: %o', err);
196
+ return 0;
197
+ }
198
+ }
199
+
200
+ // NOTE: intentionally NO close(). The `LevelDBLike` handle is shared with
201
+ // `LevelDBKVStore` and `loadOrCreateRNPeerKey` (one db per RN peer — see the
202
+ // README usage), so the driver must not own its lifecycle; closing it here
203
+ // would break the other two. Same rationale as the IndexedDB driver. The
204
+ // kernel never wires the optional close() regardless.
205
+ }
206
+
207
+ /**
208
+ * LevelDB-backed {@link IRawStorage} for React Native peers, now a thin shell
209
+ * over the shared {@link KvRawStorage} kernel driven by a {@link LevelDBStoreDriver}.
210
+ * The public name/constructor (`new LevelDBRawStorage(db)`) is unchanged so
211
+ * existing imports keep resolving; the kernel supplies the `IRawStorage` surface
212
+ * and the driver supplies LevelDB behavior.
213
+ *
214
+ * `listBlockIds`/`getApproximateBytesUsed` are re-declared here as always-present
215
+ * (the LevelDB driver always implements them, so the kernel constructor always
216
+ * wires them) — the base declares them optional, but every RN consumer relies on
217
+ * them.
218
+ */
219
+ export class LevelDBRawStorage extends KvRawStorage {
220
+ declare listBlockIds: () => AsyncIterable<BlockId>;
221
+ declare getApproximateBytesUsed: () => Promise<number>;
222
+ declare getStoreIdentity: () => StoreIdentity;
223
+
224
+ constructor(db: LevelDBLike) {
225
+ super(new LevelDBStoreDriver(db));
226
+ }
227
+ }