@optimystic/db-p2p 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 → README.md} +688 -668
- package/dist/src/cluster/block-transfer-service.d.ts +133 -10
- package/dist/src/cluster/block-transfer-service.d.ts.map +1 -1
- package/dist/src/cluster/block-transfer-service.js +155 -9
- package/dist/src/cluster/block-transfer-service.js.map +1 -1
- package/dist/src/cluster/block-transfer.d.ts +67 -7
- package/dist/src/cluster/block-transfer.d.ts.map +1 -1
- package/dist/src/cluster/block-transfer.js +127 -24
- package/dist/src/cluster/block-transfer.js.map +1 -1
- package/dist/src/cluster/certified-claims.d.ts +170 -0
- package/dist/src/cluster/certified-claims.d.ts.map +1 -0
- package/dist/src/cluster/certified-claims.js +200 -0
- package/dist/src/cluster/certified-claims.js.map +1 -0
- package/dist/src/cluster/client-signature-verifier.d.ts +23 -0
- package/dist/src/cluster/client-signature-verifier.d.ts.map +1 -0
- package/dist/src/cluster/client-signature-verifier.js +33 -0
- package/dist/src/cluster/client-signature-verifier.js.map +1 -0
- package/dist/src/cluster/cluster-policy.d.ts +9 -3
- package/dist/src/cluster/cluster-policy.d.ts.map +1 -1
- package/dist/src/cluster/cluster-policy.js +111 -27
- package/dist/src/cluster/cluster-policy.js.map +1 -1
- package/dist/src/cluster/cluster-repo.d.ts +140 -11
- package/dist/src/cluster/cluster-repo.d.ts.map +1 -1
- package/dist/src/cluster/cluster-repo.js +485 -29
- package/dist/src/cluster/cluster-repo.js.map +1 -1
- package/dist/src/cluster/commit-proof.d.ts +134 -0
- package/dist/src/cluster/commit-proof.d.ts.map +1 -0
- package/dist/src/cluster/commit-proof.js +263 -0
- package/dist/src/cluster/commit-proof.js.map +1 -0
- package/dist/src/cluster/quorum-restore.d.ts +95 -8
- package/dist/src/cluster/quorum-restore.d.ts.map +1 -1
- package/dist/src/cluster/quorum-restore.js +113 -14
- package/dist/src/cluster/quorum-restore.js.map +1 -1
- package/dist/src/cluster/rebalance-monitor.d.ts +84 -0
- package/dist/src/cluster/rebalance-monitor.d.ts.map +1 -1
- package/dist/src/cluster/rebalance-monitor.js +207 -5
- package/dist/src/cluster/rebalance-monitor.js.map +1 -1
- package/dist/src/cluster/reconcile-block.d.ts +27 -7
- package/dist/src/cluster/reconcile-block.d.ts.map +1 -1
- package/dist/src/cluster/reconcile-block.js +179 -38
- package/dist/src/cluster/reconcile-block.js.map +1 -1
- package/dist/src/cluster/service.d.ts +13 -4
- package/dist/src/cluster/service.d.ts.map +1 -1
- package/dist/src/cluster/service.js +17 -18
- package/dist/src/cluster/service.js.map +1 -1
- package/dist/src/cluster/spread-on-churn.d.ts +8 -2
- package/dist/src/cluster/spread-on-churn.d.ts.map +1 -1
- package/dist/src/cluster/spread-on-churn.js +7 -7
- package/dist/src/cluster/spread-on-churn.js.map +1 -1
- package/dist/src/cohort-topic/host.d.ts.map +1 -1
- package/dist/src/cohort-topic/host.js +8 -7
- package/dist/src/cohort-topic/host.js.map +1 -1
- package/dist/src/cohort-topic/stream-util.d.ts +7 -6
- package/dist/src/cohort-topic/stream-util.d.ts.map +1 -1
- package/dist/src/cohort-topic/stream-util.js +14 -41
- package/dist/src/cohort-topic/stream-util.js.map +1 -1
- package/dist/src/dispute/cascade.d.ts +7 -8
- package/dist/src/dispute/cascade.d.ts.map +1 -1
- package/dist/src/dispute/cascade.js +24 -7
- package/dist/src/dispute/cascade.js.map +1 -1
- package/dist/src/dispute/dispute-service.d.ts +5 -0
- package/dist/src/dispute/dispute-service.d.ts.map +1 -1
- package/dist/src/dispute/dispute-service.js +13 -3
- package/dist/src/dispute/dispute-service.js.map +1 -1
- package/dist/src/dispute/invalidation.d.ts +33 -15
- package/dist/src/dispute/invalidation.d.ts.map +1 -1
- package/dist/src/dispute/invalidation.js +127 -34
- package/dist/src/dispute/invalidation.js.map +1 -1
- package/dist/src/dispute/service.d.ts.map +1 -1
- package/dist/src/dispute/service.js +2 -1
- package/dist/src/dispute/service.js.map +1 -1
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/libp2p-key-network.d.ts +14 -10
- package/dist/src/libp2p-key-network.d.ts.map +1 -1
- package/dist/src/libp2p-key-network.js +28 -58
- package/dist/src/libp2p-key-network.js.map +1 -1
- package/dist/src/libp2p-node-base.d.ts +38 -7
- package/dist/src/libp2p-node-base.d.ts.map +1 -1
- package/dist/src/libp2p-node-base.js +148 -63
- package/dist/src/libp2p-node-base.js.map +1 -1
- package/dist/src/network/open-protocol-stream.d.ts +56 -0
- package/dist/src/network/open-protocol-stream.d.ts.map +1 -0
- package/dist/src/network/open-protocol-stream.js +60 -0
- package/dist/src/network/open-protocol-stream.js.map +1 -0
- package/dist/src/network/register-protocol-handler.d.ts +66 -0
- package/dist/src/network/register-protocol-handler.d.ts.map +1 -0
- package/dist/src/network/register-protocol-handler.js +51 -0
- package/dist/src/network/register-protocol-handler.js.map +1 -0
- package/dist/src/peer-address-book.d.ts +60 -2
- package/dist/src/peer-address-book.d.ts.map +1 -1
- package/dist/src/peer-address-book.js +89 -1
- package/dist/src/peer-address-book.js.map +1 -1
- package/dist/src/pend-validation.d.ts +65 -0
- package/dist/src/pend-validation.d.ts.map +1 -0
- package/dist/src/pend-validation.js +69 -0
- package/dist/src/pend-validation.js.map +1 -0
- package/dist/src/reactivity/notify-transport.d.ts.map +1 -1
- package/dist/src/reactivity/notify-transport.js +2 -1
- package/dist/src/reactivity/notify-transport.js.map +1 -1
- package/dist/src/reactivity/push-state-gossip.d.ts.map +1 -1
- package/dist/src/reactivity/push-state-gossip.js +2 -1
- package/dist/src/reactivity/push-state-gossip.js.map +1 -1
- package/dist/src/repo/cluster-coordinator.d.ts +32 -6
- package/dist/src/repo/cluster-coordinator.d.ts.map +1 -1
- package/dist/src/repo/cluster-coordinator.js +44 -10
- package/dist/src/repo/cluster-coordinator.js.map +1 -1
- package/dist/src/repo/coordinator-repo.d.ts +181 -25
- package/dist/src/repo/coordinator-repo.d.ts.map +1 -1
- package/dist/src/repo/coordinator-repo.js +650 -62
- package/dist/src/repo/coordinator-repo.js.map +1 -1
- package/dist/src/repo/served-repo-proxy.d.ts +30 -0
- package/dist/src/repo/served-repo-proxy.d.ts.map +1 -0
- package/dist/src/repo/served-repo-proxy.js +50 -0
- package/dist/src/repo/served-repo-proxy.js.map +1 -0
- package/dist/src/repo/service.d.ts +16 -1
- package/dist/src/repo/service.d.ts.map +1 -1
- package/dist/src/repo/service.js +18 -16
- package/dist/src/repo/service.js.map +1 -1
- package/dist/src/reputation/types.d.ts +3 -1
- package/dist/src/reputation/types.d.ts.map +1 -1
- package/dist/src/reputation/types.js +3 -1
- package/dist/src/reputation/types.js.map +1 -1
- package/dist/src/rn.d.ts +24 -2
- package/dist/src/rn.d.ts.map +1 -1
- package/dist/src/rn.js +33 -4
- package/dist/src/rn.js.map +1 -1
- package/dist/src/storage/block-archive.d.ts +153 -0
- package/dist/src/storage/block-archive.d.ts.map +1 -0
- package/dist/src/storage/block-archive.js +194 -0
- package/dist/src/storage/block-archive.js.map +1 -0
- package/dist/src/storage/block-latch.d.ts +92 -0
- package/dist/src/storage/block-latch.d.ts.map +1 -0
- package/dist/src/storage/block-latch.js +132 -0
- package/dist/src/storage/block-latch.js.map +1 -0
- package/dist/src/storage/block-storage.d.ts +169 -12
- package/dist/src/storage/block-storage.d.ts.map +1 -1
- package/dist/src/storage/block-storage.js +415 -152
- package/dist/src/storage/block-storage.js.map +1 -1
- package/dist/src/storage/cached-raw-storage.d.ts +5 -1
- package/dist/src/storage/cached-raw-storage.d.ts.map +1 -1
- package/dist/src/storage/cached-raw-storage.js +16 -1
- package/dist/src/storage/cached-raw-storage.js.map +1 -1
- package/dist/src/storage/cached-store-driver.d.ts +14 -4
- package/dist/src/storage/cached-store-driver.d.ts.map +1 -1
- package/dist/src/storage/cached-store-driver.js +39 -5
- package/dist/src/storage/cached-store-driver.js.map +1 -1
- package/dist/src/storage/i-block-storage.d.ts +70 -19
- package/dist/src/storage/i-block-storage.d.ts.map +1 -1
- package/dist/src/storage/i-block-storage.js +21 -1
- package/dist/src/storage/i-block-storage.js.map +1 -1
- package/dist/src/storage/i-raw-storage.d.ts +38 -0
- package/dist/src/storage/i-raw-storage.d.ts.map +1 -1
- package/dist/src/storage/kv-raw-storage.d.ts +14 -8
- package/dist/src/storage/kv-raw-storage.d.ts.map +1 -1
- package/dist/src/storage/kv-raw-storage.js +29 -9
- package/dist/src/storage/kv-raw-storage.js.map +1 -1
- package/dist/src/storage/memory-store-driver.d.ts +4 -1
- package/dist/src/storage/memory-store-driver.d.ts.map +1 -1
- package/dist/src/storage/memory-store-driver.js +22 -2
- package/dist/src/storage/memory-store-driver.js.map +1 -1
- package/dist/src/storage/raw-store-codec.js +2 -2
- package/dist/src/storage/raw-store-driver.d.ts +44 -3
- package/dist/src/storage/raw-store-driver.d.ts.map +1 -1
- package/dist/src/storage/shared-cache-pool.d.ts +60 -3
- package/dist/src/storage/shared-cache-pool.d.ts.map +1 -1
- package/dist/src/storage/shared-cache-pool.js +68 -4
- package/dist/src/storage/shared-cache-pool.js.map +1 -1
- package/dist/src/storage/storage-repo.d.ts +204 -26
- package/dist/src/storage/storage-repo.d.ts.map +1 -1
- package/dist/src/storage/storage-repo.js +422 -119
- package/dist/src/storage/storage-repo.js.map +1 -1
- package/dist/src/storage/store-identity.d.ts +21 -0
- package/dist/src/storage/store-identity.d.ts.map +1 -0
- package/dist/src/storage/store-identity.js +33 -0
- package/dist/src/storage/store-identity.js.map +1 -0
- package/dist/src/storage/struct.d.ts +15 -0
- package/dist/src/storage/struct.d.ts.map +1 -1
- package/dist/src/storage/with-read-cache.d.ts +92 -0
- package/dist/src/storage/with-read-cache.d.ts.map +1 -0
- package/dist/src/storage/with-read-cache.js +132 -0
- package/dist/src/storage/with-read-cache.js.map +1 -0
- package/dist/src/sync/service.d.ts +13 -3
- package/dist/src/sync/service.d.ts.map +1 -1
- package/dist/src/sync/service.js +7 -30
- package/dist/src/sync/service.js.map +1 -1
- package/dist/src/testing/mesh-harness.d.ts +75 -2
- package/dist/src/testing/mesh-harness.d.ts.map +1 -1
- package/dist/src/testing/mesh-harness.js +193 -81
- package/dist/src/testing/mesh-harness.js.map +1 -1
- package/dist/src/testing/raw-storage-conformance.d.ts +8 -0
- package/dist/src/testing/raw-storage-conformance.d.ts.map +1 -1
- package/dist/src/testing/raw-storage-conformance.js +97 -2
- package/dist/src/testing/raw-storage-conformance.js.map +1 -1
- package/package.json +5 -6
- package/src/cluster/block-transfer-service.ts +528 -312
- package/src/cluster/block-transfer.ts +547 -424
- package/src/cluster/certified-claims.ts +319 -0
- package/src/cluster/client-signature-verifier.ts +34 -0
- package/src/cluster/cluster-policy.ts +294 -203
- package/src/cluster/cluster-repo.ts +2501 -2034
- package/src/cluster/commit-proof.ts +344 -0
- package/src/cluster/quorum-restore.ts +348 -223
- package/src/cluster/rebalance-monitor.ts +539 -254
- package/src/cluster/reconcile-block.ts +404 -203
- package/src/cluster/service.ts +23 -20
- package/src/cluster/spread-on-churn.ts +352 -346
- package/src/cohort-topic/host.ts +8 -7
- package/src/cohort-topic/stream-util.ts +14 -43
- package/src/dispute/cascade.ts +31 -15
- package/src/dispute/dispute-service.ts +706 -696
- package/src/dispute/invalidation.ts +162 -52
- package/src/dispute/service.ts +126 -125
- package/src/index.ts +7 -0
- package/src/libp2p-key-network.ts +1204 -1235
- package/src/libp2p-node-base.ts +185 -70
- package/src/network/open-protocol-stream.ts +87 -0
- package/src/network/register-protocol-handler.ts +85 -0
- package/src/peer-address-book.ts +96 -2
- package/src/pend-validation.ts +89 -0
- package/src/reactivity/notify-transport.ts +2 -1
- package/src/reactivity/push-state-gossip.ts +2 -1
- package/src/repo/cluster-coordinator.ts +65 -11
- package/src/repo/coordinator-repo.ts +729 -71
- package/src/repo/served-repo-proxy.ts +55 -0
- package/src/repo/service.ts +25 -16
- package/src/reputation/types.ts +3 -1
- package/src/rn.ts +34 -4
- package/src/storage/block-archive.ts +242 -0
- package/src/storage/block-latch.ts +144 -0
- package/src/storage/block-storage.ts +787 -498
- package/src/storage/cached-raw-storage.ts +21 -1
- package/src/storage/cached-store-driver.ts +898 -859
- package/src/storage/i-block-storage.ts +172 -116
- package/src/storage/i-raw-storage.ts +40 -0
- package/src/storage/kv-raw-storage.ts +34 -9
- package/src/storage/memory-store-driver.ts +26 -2
- package/src/storage/raw-store-codec.ts +42 -42
- package/src/storage/raw-store-driver.ts +45 -3
- package/src/storage/shared-cache-pool.ts +516 -452
- package/src/storage/storage-repo.ts +1421 -1014
- package/src/storage/store-identity.ts +41 -0
- package/src/storage/struct.ts +52 -34
- package/src/storage/with-read-cache.ts +182 -0
- package/src/sync/service.ts +178 -198
- package/src/testing/mesh-harness.ts +524 -344
- package/src/testing/raw-storage-conformance.ts +114 -2
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { expect } from 'chai';
|
|
2
2
|
import type { BlockId, ActionId, IBlock, BlockHeader, Transform, Transforms } from '@optimystic/db-core';
|
|
3
|
+
import type { BlockCommitProof } from '../cluster/commit-proof.js';
|
|
3
4
|
import type { IRawStorage } from '../storage/i-raw-storage.js';
|
|
4
5
|
import type { BlockMetadata } from '../storage/struct.js';
|
|
5
6
|
import { StorageRepo } from '../storage/storage-repo.js';
|
|
6
7
|
import { BlockStorage } from '../storage/block-storage.js';
|
|
8
|
+
import { withBlockWriteLatch } from '../storage/block-latch.js';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* What `makeStorage` hands each conformance case: a fresh `IRawStorage` and a
|
|
@@ -32,6 +34,23 @@ const makeInsertTransforms = (blockId: BlockId, block: IBlock): Transforms => ({
|
|
|
32
34
|
deletes: []
|
|
33
35
|
});
|
|
34
36
|
|
|
37
|
+
/**
|
|
38
|
+
* A structurally-valid {@link BlockCommitProof} carrying a recognizable marker. Storage-level
|
|
39
|
+
* suites never VERIFY a proof (that is `commit-proof.spec.ts`); they only assert the proofs
|
|
40
|
+
* store round-trips a proof-shaped object and keeps it in its own keyspace, so the votes are
|
|
41
|
+
* deliberately empty. Exported so every proofs-store suite shares one shape.
|
|
42
|
+
*/
|
|
43
|
+
export const makeProof = (marker: string): BlockCommitProof => ({
|
|
44
|
+
v: 1,
|
|
45
|
+
messageHash: `hash-${marker}`,
|
|
46
|
+
message: { operations: [] } as unknown as BlockCommitProof['message'],
|
|
47
|
+
promises: {},
|
|
48
|
+
commits: {},
|
|
49
|
+
membershipVersion: 2,
|
|
50
|
+
membershipDigest: `digest-${marker}`,
|
|
51
|
+
peerIds: ['peer-a', 'peer-b']
|
|
52
|
+
});
|
|
53
|
+
|
|
35
54
|
async function collect<T>(iter: AsyncIterable<T>): Promise<T[]> {
|
|
36
55
|
const out: T[] = [];
|
|
37
56
|
for await (const item of iter) out.push(item);
|
|
@@ -241,6 +260,84 @@ export function runRawStorageConformance(
|
|
|
241
260
|
expect(await storage.getTransaction(blockId, 'a1' as ActionId)).to.deep.equal(transform);
|
|
242
261
|
});
|
|
243
262
|
|
|
263
|
+
// --- Commit proofs (their own (blockId, rev)-keyed store) ---
|
|
264
|
+
|
|
265
|
+
it('getBlockProof returns undefined on a miss', async () => {
|
|
266
|
+
expect(await storage.getBlockProof('block' as BlockId, 1)).to.equal(undefined);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it('commit proof round-trips', async () => {
|
|
270
|
+
const blockId = 'proof-block' as BlockId;
|
|
271
|
+
const proof = makeProof('rt');
|
|
272
|
+
await storage.saveBlockProof(blockId, 5, proof);
|
|
273
|
+
expect(await storage.getBlockProof(blockId, 5)).to.deep.equal(proof);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it('proofs are per-block and per-revision', async () => {
|
|
277
|
+
const a = 'proof-a' as BlockId;
|
|
278
|
+
const b = 'proof-b' as BlockId;
|
|
279
|
+
await storage.saveBlockProof(a, 1, makeProof('a1'));
|
|
280
|
+
await storage.saveBlockProof(a, 2, makeProof('a2'));
|
|
281
|
+
await storage.saveBlockProof(b, 1, makeProof('b1'));
|
|
282
|
+
|
|
283
|
+
expect((await storage.getBlockProof(a, 1))!.messageHash).to.equal('hash-a1');
|
|
284
|
+
expect((await storage.getBlockProof(a, 2))!.messageHash).to.equal('hash-a2');
|
|
285
|
+
expect((await storage.getBlockProof(b, 1))!.messageHash).to.equal('hash-b1');
|
|
286
|
+
expect(await storage.getBlockProof(a, 3), 'an unwritten rev on a block that has proofs')
|
|
287
|
+
.to.equal(undefined);
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
it('a later save replaces the proof for that revision only', async () => {
|
|
291
|
+
const blockId = 'proof-replace' as BlockId;
|
|
292
|
+
await storage.saveBlockProof(blockId, 1, makeProof('first'));
|
|
293
|
+
await storage.saveBlockProof(blockId, 2, makeProof('other-rev'));
|
|
294
|
+
await storage.saveBlockProof(blockId, 1, makeProof('second'));
|
|
295
|
+
|
|
296
|
+
expect((await storage.getBlockProof(blockId, 1))!.messageHash).to.equal('hash-second');
|
|
297
|
+
expect((await storage.getBlockProof(blockId, 2))!.messageHash).to.equal('hash-other-rev');
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
// The whole point of giving proofs their own store: an action id is chosen by whoever
|
|
301
|
+
// originates a write (a client's `pend`, a peer's restore archive) and is never
|
|
302
|
+
// re-derived or format-checked by the storing node, so a transaction may legitimately
|
|
303
|
+
// be named `~proof:<N>` — the id proofs USED to be filed under in the transactions
|
|
304
|
+
// store. Neither write may disturb the other, in either arrival order.
|
|
305
|
+
it('a transaction named `~proof:<N>` and the proof for revision N do not collide', async () => {
|
|
306
|
+
const blockId = 'proof-collide' as BlockId;
|
|
307
|
+
const collidingId = '~proof:5' as ActionId;
|
|
308
|
+
const transform: Transform = { insert: makeBlock('proof-collide', { items: ['committed'] }) };
|
|
309
|
+
|
|
310
|
+
// Order A: committed transform first, then the proof.
|
|
311
|
+
await storage.saveTransaction(blockId, collidingId, transform);
|
|
312
|
+
await storage.saveBlockProof(blockId, 5, makeProof('A'));
|
|
313
|
+
expect(await storage.getTransaction(blockId, collidingId), 'the committed transform survives')
|
|
314
|
+
.to.deep.equal(transform);
|
|
315
|
+
expect((await storage.getBlockProof(blockId, 5))!.messageHash, 'the proof is stored')
|
|
316
|
+
.to.equal('hash-A');
|
|
317
|
+
|
|
318
|
+
// Order B: proof first, then a transaction under the colliding id.
|
|
319
|
+
const other = 'proof-collide-b' as BlockId;
|
|
320
|
+
await storage.saveBlockProof(other, 5, makeProof('B'));
|
|
321
|
+
await storage.saveTransaction(other, collidingId, transform);
|
|
322
|
+
expect((await storage.getBlockProof(other, 5))!.messageHash, 'the proof survives')
|
|
323
|
+
.to.equal('hash-B');
|
|
324
|
+
expect(await storage.getTransaction(other, collidingId), 'the transform is stored')
|
|
325
|
+
.to.deep.equal(transform);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it('saveBlockProof snapshots — a later caller mutation does not corrupt stored state', async () => {
|
|
329
|
+
const blockId = 'proof-clone' as BlockId;
|
|
330
|
+
const proof = makeProof('clone');
|
|
331
|
+
await storage.saveBlockProof(blockId, 1, proof);
|
|
332
|
+
|
|
333
|
+
proof.peerIds.push('peer-c');
|
|
334
|
+
proof.messageHash = 'hash-mutated';
|
|
335
|
+
|
|
336
|
+
const stored = await storage.getBlockProof(blockId, 1);
|
|
337
|
+
expect(stored!.peerIds).to.deep.equal(['peer-a', 'peer-b']);
|
|
338
|
+
expect(stored!.messageHash).to.equal('hash-clone');
|
|
339
|
+
});
|
|
340
|
+
|
|
244
341
|
// --- Materialized blocks ---
|
|
245
342
|
|
|
246
343
|
it('getMaterializedBlock returns undefined on a miss', async () => {
|
|
@@ -348,6 +445,20 @@ export function runRawStorageConformance(
|
|
|
348
445
|
expect(reread.items, 'fresh read unaffected by mutation of a prior read').to.deep.equal(['original']);
|
|
349
446
|
});
|
|
350
447
|
|
|
448
|
+
// --- getStoreIdentity (optional; only when the backend implements it) ---
|
|
449
|
+
|
|
450
|
+
it('getStoreIdentity is a stable, scheme-prefixed, non-empty string', async function () {
|
|
451
|
+
const getStoreIdentity = storage.getStoreIdentity;
|
|
452
|
+
if (typeof getStoreIdentity !== 'function') {
|
|
453
|
+
this.skip();
|
|
454
|
+
} else {
|
|
455
|
+
const first = getStoreIdentity.call(storage);
|
|
456
|
+
expect(first, 'identity is a non-empty string').to.be.a('string').and.not.equal('');
|
|
457
|
+
expect(first, 'identity is scheme-prefixed').to.include(':');
|
|
458
|
+
expect(getStoreIdentity.call(storage), 'identity is stable across calls').to.equal(first);
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
|
|
351
462
|
// --- listBlockIds (optional; only when the driver implements it) ---
|
|
352
463
|
|
|
353
464
|
it('listBlockIds yields exactly the blocks with metadata', async function () {
|
|
@@ -436,12 +547,13 @@ export function runRawStorageConformance(
|
|
|
436
547
|
const blockId = 'parity-tombstone' as BlockId;
|
|
437
548
|
const bs = new BlockStorage(blockId, storage);
|
|
438
549
|
|
|
439
|
-
await
|
|
550
|
+
await withBlockWriteLatch(blockId, l =>
|
|
551
|
+
bs.saveReplica(makeBlock('parity-tombstone', { items: ['live'] }), { rev: 1, actionId: 'r1' as ActionId }, undefined, l));
|
|
440
552
|
const meta = await storage.getMetadata(blockId);
|
|
441
553
|
// saveReplica seeds open-ended coverage anchored at the replica rev, never [[0]].
|
|
442
554
|
expect(meta!.ranges, 'replica seeds open-ended [[1]]').to.deep.equal([[1]]);
|
|
443
555
|
|
|
444
|
-
const latest = await bs.saveDeletion({ rev: 2, actionId: 'd2' as ActionId });
|
|
556
|
+
const latest = await withBlockWriteLatch(blockId, l => bs.saveDeletion({ rev: 2, actionId: 'd2' as ActionId }, l));
|
|
445
557
|
expect(latest.rev).to.equal(2);
|
|
446
558
|
|
|
447
559
|
// getBlock at the tombstone rev reverse-applies { delete: true } → absent block.
|