@aztec/kv-store 0.0.1-commit.b2a5d0dd1 → 0.0.1-commit.b3d3157a
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 +8 -1
- package/dest/indexeddb/index.js +1 -1
- package/dest/interfaces/array_test_suite.d.ts +1 -1
- package/dest/interfaces/array_test_suite.d.ts.map +1 -1
- package/dest/interfaces/array_test_suite.js +33 -34
- package/dest/interfaces/index.d.ts +2 -2
- package/dest/interfaces/index.d.ts.map +1 -1
- package/dest/interfaces/map_test_suite.d.ts +1 -1
- package/dest/interfaces/map_test_suite.d.ts.map +1 -1
- package/dest/interfaces/map_test_suite.js +32 -33
- package/dest/interfaces/multi_map_test_suite.d.ts +1 -1
- package/dest/interfaces/multi_map_test_suite.d.ts.map +1 -1
- package/dest/interfaces/multi_map_test_suite.js +68 -69
- package/dest/interfaces/set_test_suite.d.ts +1 -1
- package/dest/interfaces/set_test_suite.d.ts.map +1 -1
- package/dest/interfaces/set_test_suite.js +13 -14
- package/dest/interfaces/singleton_test_suite.d.ts +1 -1
- package/dest/interfaces/singleton_test_suite.d.ts.map +1 -1
- package/dest/interfaces/singleton_test_suite.js +6 -7
- package/dest/lmdb/index.js +2 -2
- package/dest/lmdb-v2/factory.d.ts +28 -3
- package/dest/lmdb-v2/factory.d.ts.map +1 -1
- package/dest/lmdb-v2/factory.js +61 -10
- package/dest/lmdb-v2/store.d.ts +2 -2
- package/dest/lmdb-v2/store.d.ts.map +1 -1
- package/dest/lmdb-v2/store.js +4 -4
- package/dest/sqlite-opfs/array.js +2 -2
- package/dest/sqlite-opfs/errors.d.ts +27 -0
- package/dest/sqlite-opfs/errors.d.ts.map +1 -0
- package/dest/sqlite-opfs/errors.js +34 -0
- package/dest/sqlite-opfs/index.d.ts +10 -1
- package/dest/sqlite-opfs/index.d.ts.map +1 -1
- package/dest/sqlite-opfs/index.js +10 -1
- package/dest/sqlite-opfs/internal/ordered-binary-browser.d.ts +32 -0
- package/dest/sqlite-opfs/internal/ordered-binary-browser.d.ts.map +1 -0
- package/dest/sqlite-opfs/internal/ordered-binary-browser.js +448 -0
- package/dest/sqlite-opfs/map.d.ts +2 -2
- package/dest/sqlite-opfs/map.d.ts.map +1 -1
- package/dest/sqlite-opfs/map.js +2 -2
- package/dest/sqlite-opfs/messages.d.ts +9 -1
- package/dest/sqlite-opfs/messages.d.ts.map +1 -1
- package/dest/sqlite-opfs/messages.js +1 -1
- package/dest/sqlite-opfs/singleton.js +2 -2
- package/dest/sqlite-opfs/store.d.ts +11 -2
- package/dest/sqlite-opfs/store.d.ts.map +1 -1
- package/dest/sqlite-opfs/store.js +51 -12
- package/dest/sqlite-opfs/worker.js +63 -8
- package/dest/stores/l2_tips_store.d.ts +3 -3
- package/dest/stores/l2_tips_store.d.ts.map +1 -1
- package/dest/stores/l2_tips_store.js +2 -2
- package/package.json +21 -21
- package/src/indexeddb/index.ts +1 -1
- package/src/interfaces/array_test_suite.ts +33 -35
- package/src/interfaces/index.ts +1 -1
- package/src/interfaces/map_test_suite.ts +32 -34
- package/src/interfaces/multi_map_test_suite.ts +65 -67
- package/src/interfaces/set_test_suite.ts +13 -15
- package/src/interfaces/singleton_test_suite.ts +6 -8
- package/src/lmdb/index.ts +2 -2
- package/src/lmdb-v2/factory.ts +79 -9
- package/src/lmdb-v2/store.ts +4 -2
- package/src/sqlite-opfs/array.ts +2 -2
- package/src/sqlite-opfs/errors.ts +44 -0
- package/src/sqlite-opfs/index.ts +13 -1
- package/src/sqlite-opfs/internal/ordered-binary-browser.js +465 -0
- package/src/sqlite-opfs/map.ts +2 -2
- package/src/sqlite-opfs/messages.ts +13 -2
- package/src/sqlite-opfs/singleton.ts +2 -2
- package/src/sqlite-opfs/store.ts +53 -5
- package/src/sqlite-opfs/worker.ts +78 -9
- package/src/stores/l2_tips_store.ts +3 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SerialQueue } from '@aztec/foundation/queue';
|
|
2
2
|
import { SQLiteOPFSAztecArray } from './array.js';
|
|
3
|
+
import { SqliteEncryptionError } from './errors.js';
|
|
3
4
|
import { SQLiteOPFSAztecMap } from './map.js';
|
|
4
5
|
import { SQLiteOPFSAztecMultiMap } from './multi_map.js';
|
|
5
6
|
import { SQLiteOPFSAztecSet } from './set.js';
|
|
@@ -55,20 +56,47 @@ import { SQLiteOPFSAztecSingleton } from './singleton.js';
|
|
|
55
56
|
* Pass `poolDirectory` to place the SAH Pool in a non-default OPFS subdirectory —
|
|
56
57
|
* required when multiple stores coexist in the same tab, because the SAH Pool holds
|
|
57
58
|
* an exclusive lock on its directory.
|
|
58
|
-
|
|
59
|
+
*
|
|
60
|
+
* Pass `encryptionKey` (exactly 32 bytes) to enable at-rest encryption via sqlite3mc's
|
|
61
|
+
* ChaCha20 page cipher. The key buffer is **transferred** to the worker — its
|
|
62
|
+
* ArrayBuffer detaches on the caller side after `postMessage`. This is intentional:
|
|
63
|
+
* the API encodes a one-key-one-owner invariant. A caller that wants to use the same
|
|
64
|
+
* key for multiple stores must explicitly clone it per call (e.g.
|
|
65
|
+
* `new Uint8Array(savedKey)`), making the duplication a visible, deliberate decision
|
|
66
|
+
* rather than a silent structured-clone operation. The default path (one `.open()`,
|
|
67
|
+
* one consumption of the key) leaves zero key bytes on the main thread after the call.
|
|
68
|
+
*/ static async open(log, name, ephemeral = false, poolDirectory, encryptionKey) {
|
|
69
|
+
if (encryptionKey !== undefined && encryptionKey.length !== 32) {
|
|
70
|
+
throw new SqliteEncryptionError('invalid_key_length', `encryptionKey must be 32 bytes (got ${encryptionKey.length})`);
|
|
71
|
+
}
|
|
72
|
+
if (encryptionKey !== undefined && ephemeral) {
|
|
73
|
+
throw new SqliteEncryptionError('encryption_not_supported_for_ephemeral', 'encryptionKey is not supported for ephemeral (:memory:) stores');
|
|
74
|
+
}
|
|
59
75
|
const dbName = name && !ephemeral ? name : `tmp-${globalThis.crypto.getRandomValues(new Uint8Array(8)).join('')}`;
|
|
60
|
-
log.debug(`Opening SQLite-OPFS ${ephemeral ? 'ephemeral ' : ''}database ${dbName}`);
|
|
76
|
+
log.debug(`Opening SQLite-OPFS ${ephemeral ? 'ephemeral ' : ''}${encryptionKey ? 'encrypted ' : ''}database ${dbName}`);
|
|
61
77
|
const worker = new Worker(new URL('./worker.js', import.meta.url), {
|
|
62
78
|
type: 'module'
|
|
63
79
|
});
|
|
64
80
|
const store = new AztecSQLiteOPFSStore(worker, dbName, log, ephemeral);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
81
|
+
// Transfer (not clone) the key buffer to the worker so we don't leave a
|
|
82
|
+
// second copy on the main thread. Caveat: this detaches the caller's
|
|
83
|
+
// encryptionKey.buffer — subsequent reads from the same Uint8Array are empty.
|
|
84
|
+
const transfer = encryptionKey ? [
|
|
85
|
+
encryptionKey.buffer
|
|
86
|
+
] : undefined;
|
|
87
|
+
try {
|
|
88
|
+
await store.#sendRequest({
|
|
89
|
+
type: 'init',
|
|
90
|
+
id: store.#allocId(),
|
|
91
|
+
dbName,
|
|
92
|
+
ephemeral,
|
|
93
|
+
poolDirectory,
|
|
94
|
+
encryptionKey
|
|
95
|
+
}, transfer);
|
|
96
|
+
} catch (err) {
|
|
97
|
+
worker.terminate();
|
|
98
|
+
throw err;
|
|
99
|
+
}
|
|
72
100
|
return store;
|
|
73
101
|
}
|
|
74
102
|
openMap(name) {
|
|
@@ -224,19 +252,30 @@ import { SQLiteOPFSAztecSingleton } from './singleton.js';
|
|
|
224
252
|
}
|
|
225
253
|
this.#pending.clear();
|
|
226
254
|
}
|
|
227
|
-
#sendRequest(req) {
|
|
255
|
+
#sendRequest(req, transfer) {
|
|
228
256
|
return new Promise((resolve, reject)=>{
|
|
229
257
|
this.#pending.set(req.id, {
|
|
230
258
|
resolve: (resp)=>{
|
|
231
259
|
if (resp.type === 'err') {
|
|
232
|
-
|
|
260
|
+
// Re-hydrate encryption-shaped errors as the typed class so consumers
|
|
261
|
+
// can pattern-match on `instanceof SqliteEncryptionError`. Plain
|
|
262
|
+
// errors stay plain — the wire protocol only tags encryption paths.
|
|
263
|
+
if (resp.encryptionCode !== undefined) {
|
|
264
|
+
reject(new SqliteEncryptionError(resp.encryptionCode, resp.message));
|
|
265
|
+
} else {
|
|
266
|
+
reject(new Error(resp.message));
|
|
267
|
+
}
|
|
233
268
|
} else {
|
|
234
269
|
resolve(resp);
|
|
235
270
|
}
|
|
236
271
|
},
|
|
237
272
|
reject
|
|
238
273
|
});
|
|
239
|
-
|
|
274
|
+
if (transfer && transfer.length > 0) {
|
|
275
|
+
this.#worker.postMessage(req, transfer);
|
|
276
|
+
} else {
|
|
277
|
+
this.#worker.postMessage(req);
|
|
278
|
+
}
|
|
240
279
|
});
|
|
241
280
|
}
|
|
242
281
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference lib="webworker" />
|
|
2
|
-
import sqlite3InitModule from '@
|
|
2
|
+
import sqlite3InitModule from '@aztec/sqlite3mc-wasm';
|
|
3
|
+
import { SqliteEncryptionError, isDecryptFailureMessage } from './errors.js';
|
|
3
4
|
const SCHEMA_SQL = `
|
|
4
5
|
CREATE TABLE IF NOT EXISTS data (
|
|
5
6
|
slot TEXT NOT NULL PRIMARY KEY,
|
|
@@ -16,29 +17,60 @@ const SCHEMA_SQL = `
|
|
|
16
17
|
`;
|
|
17
18
|
const DEFAULT_SAH_POOL_DIRECTORY = '.aztec-kv';
|
|
18
19
|
const SAH_POOL_VFS_NAME = 'aztec-kv-opfs';
|
|
20
|
+
const MC_SAH_POOL_VFS_NAME = `multipleciphers-${SAH_POOL_VFS_NAME}`;
|
|
19
21
|
let sqlite3;
|
|
20
22
|
let pool;
|
|
21
23
|
let db;
|
|
22
24
|
let dbPath;
|
|
23
25
|
async function ensurePool(directory) {
|
|
24
26
|
sqlite3 ??= await sqlite3InitModule();
|
|
27
|
+
const s = sqlite3;
|
|
25
28
|
if (!pool) {
|
|
26
|
-
pool = await
|
|
29
|
+
pool = await s.installOpfsSAHPoolVfs({
|
|
27
30
|
name: SAH_POOL_VFS_NAME,
|
|
28
31
|
directory,
|
|
29
32
|
initialCapacity: 8
|
|
30
33
|
});
|
|
34
|
+
// Register a sqlite3mc-wrapped VFS pointing at our SAH Pool VFS.
|
|
35
|
+
// Encrypted DBs must be opened through this wrapper so sqlite3mc can
|
|
36
|
+
// intercept file I/O; plain DBs continue using the SAH Pool VFS directly.
|
|
37
|
+
// The wrapper name is `multipleciphers-<underlying>`.
|
|
38
|
+
s.capi.sqlite3mc_vfs_create(SAH_POOL_VFS_NAME, 0);
|
|
31
39
|
}
|
|
32
40
|
return pool;
|
|
33
41
|
}
|
|
34
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Applies sqlite3mc's ChaCha20 page cipher using a pre-derived 32-byte key.
|
|
44
|
+
* The PRAGMAs must run before any schema DDL so sqlite3mc can decrypt existing
|
|
45
|
+
* pages and encrypt new ones. Zeroes the caller-held key array after the PRAGMA
|
|
46
|
+
* completes to minimize residency of the raw key bytes outside sqlite3mc's heap.
|
|
47
|
+
*/ function applyEncryptionKey(conn, key) {
|
|
48
|
+
const hex = Array.from(key, (b)=>b.toString(16).padStart(2, '0')).join('');
|
|
49
|
+
conn.exec(`PRAGMA cipher = 'chacha20'`);
|
|
50
|
+
conn.exec(`PRAGMA key = "x'${hex}'"`);
|
|
51
|
+
key.fill(0);
|
|
52
|
+
}
|
|
53
|
+
async function handleInit(dbName, ephemeral, directory, encryptionKey) {
|
|
35
54
|
sqlite3 ??= await sqlite3InitModule();
|
|
55
|
+
const s = sqlite3;
|
|
56
|
+
if (encryptionKey !== undefined && ephemeral) {
|
|
57
|
+
throw new SqliteEncryptionError('encryption_not_supported_for_ephemeral', 'encryptionKey is not supported for ephemeral (:memory:) stores');
|
|
58
|
+
}
|
|
36
59
|
if (ephemeral) {
|
|
37
|
-
db = new
|
|
60
|
+
db = new s.oo1.DB(':memory:', 'c');
|
|
38
61
|
} else {
|
|
39
|
-
|
|
62
|
+
await ensurePool(directory ?? DEFAULT_SAH_POOL_DIRECTORY);
|
|
40
63
|
dbPath = normalizeDbPath(dbName);
|
|
41
|
-
|
|
64
|
+
if (encryptionKey !== undefined) {
|
|
65
|
+
db = new s.oo1.DB({
|
|
66
|
+
filename: dbPath,
|
|
67
|
+
flags: 'c',
|
|
68
|
+
vfs: MC_SAH_POOL_VFS_NAME
|
|
69
|
+
});
|
|
70
|
+
applyEncryptionKey(db, encryptionKey);
|
|
71
|
+
} else {
|
|
72
|
+
db = new pool.OpfsSAHPoolDb(dbPath);
|
|
73
|
+
}
|
|
42
74
|
}
|
|
43
75
|
runSql(SCHEMA_SQL);
|
|
44
76
|
}
|
|
@@ -115,7 +147,7 @@ self.onmessage = async (ev)=>{
|
|
|
115
147
|
try {
|
|
116
148
|
switch(req.type){
|
|
117
149
|
case 'init':
|
|
118
|
-
await handleInit(req.dbName, req.ephemeral, req.poolDirectory);
|
|
150
|
+
await handleInit(req.dbName, req.ephemeral, req.poolDirectory, req.encryptionKey);
|
|
119
151
|
return respond({
|
|
120
152
|
type: 'ok',
|
|
121
153
|
id: req.id
|
|
@@ -188,7 +220,30 @@ self.onmessage = async (ev)=>{
|
|
|
188
220
|
respond({
|
|
189
221
|
type: 'err',
|
|
190
222
|
id: req.id,
|
|
191
|
-
message
|
|
223
|
+
message,
|
|
224
|
+
encryptionCode: detectEncryptionCode(req, err, message)
|
|
192
225
|
});
|
|
193
226
|
}
|
|
194
227
|
};
|
|
228
|
+
/**
|
|
229
|
+
* Maps a thrown error during request handling to a typed encryption code, so the
|
|
230
|
+
* main thread can re-hydrate it as a {@link SqliteEncryptionError}. Returns
|
|
231
|
+
* `undefined` for non-encryption errors (preserves the existing untyped path).
|
|
232
|
+
*
|
|
233
|
+
* Two sources:
|
|
234
|
+
* - The error was already a `SqliteEncryptionError` (pre-flight throws inside
|
|
235
|
+
* this worker — e.g. ephemeral + encryptionKey). Forward its code as-is.
|
|
236
|
+
* - The error came from SQLite/sqlite3mc with a known decrypt-failure message
|
|
237
|
+
* during an `init` request. Both "wrong key supplied" and "no key supplied
|
|
238
|
+
* to an encrypted DB" surface as SQLITE_NOTADB ("file is not a database") —
|
|
239
|
+
* we don't constrain on `req.encryptionKey` because the no-key-on-encrypted-DB
|
|
240
|
+
* case is exactly when the caller most needs the typed signal.
|
|
241
|
+
*/ function detectEncryptionCode(req, err, message) {
|
|
242
|
+
if (err instanceof SqliteEncryptionError) {
|
|
243
|
+
return err.code;
|
|
244
|
+
}
|
|
245
|
+
if (req.type === 'init' && isDecryptFailureMessage(message)) {
|
|
246
|
+
return 'decrypt_failed';
|
|
247
|
+
}
|
|
248
|
+
return undefined;
|
|
249
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
2
|
-
import { type L2BlockTag, L2TipsStoreBase } from '@aztec/stdlib/block';
|
|
2
|
+
import { type BlockHash, type L2BlockTag, L2TipsStoreBase } from '@aztec/stdlib/block';
|
|
3
3
|
import { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
4
4
|
import type { AztecAsyncKVStore } from '../interfaces/store.js';
|
|
5
5
|
/**
|
|
@@ -12,7 +12,7 @@ export declare class L2TipsKVStore extends L2TipsStoreBase {
|
|
|
12
12
|
private readonly l2BlockHashesStore;
|
|
13
13
|
private readonly l2BlockNumberToCheckpointNumberStore;
|
|
14
14
|
private readonly l2CheckpointStore;
|
|
15
|
-
constructor(store: AztecAsyncKVStore, namespace: string);
|
|
15
|
+
constructor(store: AztecAsyncKVStore, namespace: string, initialBlockHash: BlockHash);
|
|
16
16
|
protected getTip(tag: L2BlockTag): Promise<BlockNumber | undefined>;
|
|
17
17
|
protected setTip(tag: L2BlockTag, blockNumber: BlockNumber): Promise<void>;
|
|
18
18
|
protected getStoredBlockHash(blockNumber: BlockNumber): Promise<string | undefined>;
|
|
@@ -26,4 +26,4 @@ export declare class L2TipsKVStore extends L2TipsStoreBase {
|
|
|
26
26
|
protected deleteCheckpointsBefore(checkpointNumber: CheckpointNumber): Promise<void>;
|
|
27
27
|
protected runInTransaction<T>(fn: () => Promise<T>): Promise<T>;
|
|
28
28
|
}
|
|
29
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibDJfdGlwc19zdG9yZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N0b3Jlcy9sMl90aXBzX3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNoRixPQUFPLEVBQUUsS0FBSyxTQUFTLEVBQUUsS0FBSyxVQUFVLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFHL0QsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUVoRTs7O0dBR0c7QUFDSCxxQkFBYSxhQUFjLFNBQVEsZUFBZTtJQU85QyxPQUFPLENBQUMsS0FBSztJQU5mLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUF5QztJQUNyRSxPQUFPLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFxQztJQUN4RSxPQUFPLENBQUMsUUFBUSxDQUFDLG9DQUFvQyxDQUErQztJQUNwRyxPQUFPLENBQUMsUUFBUSxDQUFDLGlCQUFpQixDQUEwQztJQUU1RSxZQUNVLEtBQUssRUFBRSxpQkFBaUIsRUFDaEMsU0FBUyxFQUFFLE1BQU0sRUFDakIsZ0JBQWdCLEVBQUUsU0FBUyxFQVM1QjtJQUVELFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsV0FBVyxHQUFHLFNBQVMsQ0FBQyxDQUVsRTtJQUVELFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsV0FBVyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FFekU7SUFFRCxTQUFTLENBQUMsa0JBQWtCLENBQUMsV0FBVyxFQUFFLFdBQVcsR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUVsRjtJQUVELFNBQVMsQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FFNUU7SUFFRCxVQUFnQix1QkFBdUIsQ0FBQyxXQUFXLEVBQUUsV0FBVyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FJL0U7SUFFRCxTQUFTLENBQUMsMkJBQTJCLENBQUMsV0FBVyxFQUFFLFdBQVcsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLEdBQUcsU0FBUyxDQUFDLENBRXJHO0lBRUQsU0FBUyxDQUFDLDJCQUEyQixDQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUVqSDtJQUVELFVBQWdCLDZCQUE2QixDQUFDLFdBQVcsRUFBRSxXQUFXLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUlyRjtJQUVELFVBQWdCLGFBQWEsQ0FBQyxnQkFBZ0IsRUFBRSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsbUJBQW1CLEdBQUcsU0FBUyxDQUFDLENBTTFHO0lBRUQsU0FBUyxDQUFDLGtCQUFrQixDQUFDLFVBQVUsRUFBRSxtQkFBbUIsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBRTNFO0lBRUQsVUFBZ0IsdUJBQXVCLENBQUMsZ0JBQWdCLEVBQUUsZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUl6RjtJQUVELFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLE1BQU0sT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FFOUQ7Q0FDRiJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"l2_tips_store.d.ts","sourceRoot":"","sources":["../../src/stores/l2_tips_store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAAE,KAAK,UAAU,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"l2_tips_store.d.ts","sourceRoot":"","sources":["../../src/stores/l2_tips_store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAG/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE;;;GAGG;AACH,qBAAa,aAAc,SAAQ,eAAe;IAO9C,OAAO,CAAC,KAAK;IANf,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyC;IACrE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqC;IACxE,OAAO,CAAC,QAAQ,CAAC,oCAAoC,CAA+C;IACpG,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA0C;IAE5E,YACU,KAAK,EAAE,iBAAiB,EAChC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,SAAS,EAS5B;IAED,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAElE;IAED,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzE;IAED,SAAS,CAAC,kBAAkB,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAElF;IAED,SAAS,CAAC,YAAY,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;IAED,UAAgB,uBAAuB,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/E;IAED,SAAS,CAAC,2BAA2B,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAErG;IAED,SAAS,CAAC,2BAA2B,CAAC,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjH;IAED,UAAgB,6BAA6B,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrF;IAED,UAAgB,aAAa,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAM1G;IAED,SAAS,CAAC,kBAAkB,CAAC,UAAU,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3E;IAED,UAAgB,uBAAuB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIzF;IAED,SAAS,CAAC,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAE9D;CACF"}
|
|
@@ -9,8 +9,8 @@ import { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
|
9
9
|
l2BlockHashesStore;
|
|
10
10
|
l2BlockNumberToCheckpointNumberStore;
|
|
11
11
|
l2CheckpointStore;
|
|
12
|
-
constructor(store, namespace){
|
|
13
|
-
super(), this.store = store;
|
|
12
|
+
constructor(store, namespace, initialBlockHash){
|
|
13
|
+
super(initialBlockHash), this.store = store;
|
|
14
14
|
this.l2TipsStore = store.openMap([
|
|
15
15
|
namespace,
|
|
16
16
|
'l2_tips'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/kv-store",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.b3d3157a",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/interfaces/index.js",
|
|
@@ -11,14 +11,24 @@
|
|
|
11
11
|
"./sqlite-opfs": "./dest/sqlite-opfs/index.js",
|
|
12
12
|
"./stores": "./dest/stores/index.js"
|
|
13
13
|
},
|
|
14
|
+
"imports": {
|
|
15
|
+
"#msgpackr": {
|
|
16
|
+
"browser": "msgpackr/index-no-eval",
|
|
17
|
+
"default": "msgpackr"
|
|
18
|
+
},
|
|
19
|
+
"#ordered-binary": {
|
|
20
|
+
"browser": "./dest/sqlite-opfs/internal/ordered-binary-browser.js",
|
|
21
|
+
"default": "ordered-binary"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
14
24
|
"scripts": {
|
|
15
25
|
"build": "yarn clean && ../scripts/tsc.sh",
|
|
16
26
|
"build:dev": "../scripts/tsc.sh --watch",
|
|
17
27
|
"clean": "rm -rf ./dest .tsbuildinfo",
|
|
18
|
-
"test:node": "
|
|
19
|
-
"test:browser": "
|
|
20
|
-
"bench:browser": "VITE_BENCH=1 vitest run --
|
|
21
|
-
"test": "
|
|
28
|
+
"test:node": "vitest run --project node",
|
|
29
|
+
"test:browser": "bash scripts/run-browser-tests.sh",
|
|
30
|
+
"bench:browser": "VITE_BENCH=1 vitest run --project browser src/bench",
|
|
31
|
+
"test": "vitest run",
|
|
22
32
|
"test:jest": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
|
|
23
33
|
},
|
|
24
34
|
"inherits": [
|
|
@@ -26,12 +36,12 @@
|
|
|
26
36
|
"./package.local.json"
|
|
27
37
|
],
|
|
28
38
|
"dependencies": {
|
|
29
|
-
"@aztec/constants": "0.0.1-commit.
|
|
30
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
31
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
32
|
-
"@aztec/native": "0.0.1-commit.
|
|
33
|
-
"@aztec/
|
|
34
|
-
"@
|
|
39
|
+
"@aztec/constants": "0.0.1-commit.b3d3157a",
|
|
40
|
+
"@aztec/ethereum": "0.0.1-commit.b3d3157a",
|
|
41
|
+
"@aztec/foundation": "0.0.1-commit.b3d3157a",
|
|
42
|
+
"@aztec/native": "0.0.1-commit.b3d3157a",
|
|
43
|
+
"@aztec/sqlite3mc-wasm": "0.0.1-commit.b3d3157a",
|
|
44
|
+
"@aztec/stdlib": "0.0.1-commit.b3d3157a",
|
|
35
45
|
"idb": "^8.0.0",
|
|
36
46
|
"lmdb": "^3.2.0",
|
|
37
47
|
"msgpackr": "^1.11.2",
|
|
@@ -40,23 +50,13 @@
|
|
|
40
50
|
},
|
|
41
51
|
"devDependencies": {
|
|
42
52
|
"@jest/globals": "^30.0.0",
|
|
43
|
-
"@types/chai": "^5.0.1",
|
|
44
|
-
"@types/chai-as-promised": "^8.0.1",
|
|
45
53
|
"@types/jest": "^30.0.0",
|
|
46
|
-
"@types/mocha": "^10.0.10",
|
|
47
|
-
"@types/mocha-each": "^2.0.4",
|
|
48
54
|
"@types/node": "^22.15.17",
|
|
49
|
-
"@types/sinon": "^17.0.3",
|
|
50
55
|
"@typescript/native-preview": "7.0.0-dev.20260113.1",
|
|
51
56
|
"@vitest/browser-playwright": "^4.0.0",
|
|
52
57
|
"buffer": "^6.0.3",
|
|
53
|
-
"chai": "^5.1.2",
|
|
54
|
-
"chai-as-promised": "^8.0.1",
|
|
55
58
|
"jest": "^30.0.0",
|
|
56
|
-
"mocha": "^10.8.2",
|
|
57
|
-
"mocha-each": "^2.0.1",
|
|
58
59
|
"playwright": "1.49.0",
|
|
59
|
-
"sinon": "^19.0.2",
|
|
60
60
|
"ts-node": "^10.9.1",
|
|
61
61
|
"typescript": "^5.3.3",
|
|
62
62
|
"util": "^0.12.5",
|
package/src/indexeddb/index.ts
CHANGED
|
@@ -23,7 +23,7 @@ export async function createStore(
|
|
|
23
23
|
: `Creating ${name} ephemeral data store with map size ${config.dataStoreMapSizeKb} KB`,
|
|
24
24
|
);
|
|
25
25
|
const store = await AztecIndexedDBStore.open(createLogger('kv-store:indexeddb'), dataDirectory ?? '', false);
|
|
26
|
-
return initStoreForRollupAndSchemaVersion(store, schemaVersion, config.
|
|
26
|
+
return initStoreForRollupAndSchemaVersion(store, schemaVersion, config.rollupAddress, log);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
export function openTmpStore(ephemeral: boolean = false): Promise<AztecIndexedDBStore> {
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { toArray } from '@aztec/foundation/iterable';
|
|
2
2
|
|
|
3
|
-
import { expect } from 'chai';
|
|
4
|
-
|
|
5
3
|
import type { AztecArray, AztecAsyncArray } from './array.js';
|
|
6
4
|
import type { AztecAsyncKVStore, AztecKVStore } from './store.js';
|
|
7
5
|
import { isSyncStore } from './utils.js';
|
|
@@ -53,12 +51,12 @@ export function describeAztecArray(
|
|
|
53
51
|
await arr.push(2);
|
|
54
52
|
await arr.push(3);
|
|
55
53
|
|
|
56
|
-
expect(await length()).
|
|
54
|
+
expect(await length()).toBe(3);
|
|
57
55
|
|
|
58
|
-
expect(await arr.pop()).
|
|
59
|
-
expect(await arr.pop()).
|
|
60
|
-
expect(await arr.pop()).
|
|
61
|
-
expect(await arr.pop()).
|
|
56
|
+
expect(await arr.pop()).toBe(3);
|
|
57
|
+
expect(await arr.pop()).toBe(2);
|
|
58
|
+
expect(await arr.pop()).toBe(1);
|
|
59
|
+
expect(await arr.pop()).toBe(undefined);
|
|
62
60
|
});
|
|
63
61
|
|
|
64
62
|
it('should be able to get values by index', async () => {
|
|
@@ -66,14 +64,14 @@ export function describeAztecArray(
|
|
|
66
64
|
await arr.push(2);
|
|
67
65
|
await arr.push(3);
|
|
68
66
|
|
|
69
|
-
expect(await at(0)).
|
|
70
|
-
expect(await at(1)).
|
|
71
|
-
expect(await at(2)).
|
|
72
|
-
expect(await at(3)).
|
|
73
|
-
expect(await at(-1)).
|
|
74
|
-
expect(await at(-2)).
|
|
75
|
-
expect(await at(-3)).
|
|
76
|
-
expect(await at(-4)).
|
|
67
|
+
expect(await at(0)).toBe(1);
|
|
68
|
+
expect(await at(1)).toBe(2);
|
|
69
|
+
expect(await at(2)).toBe(3);
|
|
70
|
+
expect(await at(3)).toBe(undefined);
|
|
71
|
+
expect(await at(-1)).toBe(3);
|
|
72
|
+
expect(await at(-2)).toBe(2);
|
|
73
|
+
expect(await at(-3)).toBe(1);
|
|
74
|
+
expect(await at(-4)).toBe(undefined);
|
|
77
75
|
});
|
|
78
76
|
|
|
79
77
|
it('should be able to set values by index', async () => {
|
|
@@ -81,27 +79,27 @@ export function describeAztecArray(
|
|
|
81
79
|
await arr.push(2);
|
|
82
80
|
await arr.push(3);
|
|
83
81
|
|
|
84
|
-
expect(await arr.setAt(0, 4)).
|
|
85
|
-
expect(await arr.setAt(1, 5)).
|
|
86
|
-
expect(await arr.setAt(2, 6)).
|
|
82
|
+
expect(await arr.setAt(0, 4)).toBe(true);
|
|
83
|
+
expect(await arr.setAt(1, 5)).toBe(true);
|
|
84
|
+
expect(await arr.setAt(2, 6)).toBe(true);
|
|
87
85
|
|
|
88
|
-
expect(await arr.setAt(3, 7)).
|
|
86
|
+
expect(await arr.setAt(3, 7)).toBe(false);
|
|
89
87
|
|
|
90
|
-
expect(await at(0)).
|
|
91
|
-
expect(await at(1)).
|
|
92
|
-
expect(await at(2)).
|
|
93
|
-
expect(await at(3)).
|
|
88
|
+
expect(await at(0)).toBe(4);
|
|
89
|
+
expect(await at(1)).toBe(5);
|
|
90
|
+
expect(await at(2)).toBe(6);
|
|
91
|
+
expect(await at(3)).toBe(undefined);
|
|
94
92
|
|
|
95
|
-
expect(await arr.setAt(-1, 8)).
|
|
96
|
-
expect(await arr.setAt(-2, 9)).
|
|
97
|
-
expect(await arr.setAt(-3, 10)).
|
|
93
|
+
expect(await arr.setAt(-1, 8)).toBe(true);
|
|
94
|
+
expect(await arr.setAt(-2, 9)).toBe(true);
|
|
95
|
+
expect(await arr.setAt(-3, 10)).toBe(true);
|
|
98
96
|
|
|
99
|
-
expect(await arr.setAt(-4, 11)).
|
|
97
|
+
expect(await arr.setAt(-4, 11)).toBe(false);
|
|
100
98
|
|
|
101
|
-
expect(await at(-1)).
|
|
102
|
-
expect(await at(-2)).
|
|
103
|
-
expect(await at(-3)).
|
|
104
|
-
expect(await at(-4)).
|
|
99
|
+
expect(await at(-1)).toBe(8);
|
|
100
|
+
expect(await at(-2)).toBe(9);
|
|
101
|
+
expect(await at(-3)).toBe(10);
|
|
102
|
+
expect(await at(-4)).toBe(undefined);
|
|
105
103
|
});
|
|
106
104
|
|
|
107
105
|
it('should be able to iterate over values', async () => {
|
|
@@ -109,8 +107,8 @@ export function describeAztecArray(
|
|
|
109
107
|
await arr.push(2);
|
|
110
108
|
await arr.push(3);
|
|
111
109
|
|
|
112
|
-
expect(await values()).
|
|
113
|
-
expect(await entries()).
|
|
110
|
+
expect(await values()).toEqual([1, 2, 3]);
|
|
111
|
+
expect(await entries()).toEqual([
|
|
114
112
|
[0, 1],
|
|
115
113
|
[1, 2],
|
|
116
114
|
[2, 3],
|
|
@@ -123,8 +121,8 @@ export function describeAztecArray(
|
|
|
123
121
|
await arr.push(3);
|
|
124
122
|
|
|
125
123
|
const arr2 = store.openArray<number>('test');
|
|
126
|
-
expect(await length(arr2)).
|
|
127
|
-
expect(await values(arr2)).
|
|
124
|
+
expect(await length(arr2)).toBe(3);
|
|
125
|
+
expect(await values(arr2)).toEqual(await values());
|
|
128
126
|
});
|
|
129
127
|
});
|
|
130
128
|
}
|
package/src/interfaces/index.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { toArray } from '@aztec/foundation/iterable';
|
|
2
2
|
|
|
3
|
-
import { expect } from 'chai';
|
|
4
|
-
|
|
5
3
|
import type { Key, Range } from './common.js';
|
|
6
4
|
import type { AztecAsyncMap, AztecMap } from './map.js';
|
|
7
5
|
import type { AztecAsyncKVStore, AztecKVStore } from './store.js';
|
|
@@ -59,9 +57,9 @@ export function describeAztecMap(
|
|
|
59
57
|
await map.set('foo', 'bar');
|
|
60
58
|
await map.set('baz', 'qux');
|
|
61
59
|
|
|
62
|
-
expect(await get('foo')).
|
|
63
|
-
expect(await get('baz')).
|
|
64
|
-
expect(await get('quux')).
|
|
60
|
+
expect(await get('foo')).toBe('bar');
|
|
61
|
+
expect(await get('baz')).toBe('qux');
|
|
62
|
+
expect(await get('quux')).toBe(undefined);
|
|
65
63
|
});
|
|
66
64
|
|
|
67
65
|
it('should be able to set many values', async () => {
|
|
@@ -69,7 +67,7 @@ export function describeAztecMap(
|
|
|
69
67
|
await map.setMany(pairs);
|
|
70
68
|
|
|
71
69
|
for (const { key, value } of pairs) {
|
|
72
|
-
expect(await get(key)).
|
|
70
|
+
expect(await get(key)).toBe(value);
|
|
73
71
|
}
|
|
74
72
|
});
|
|
75
73
|
|
|
@@ -77,14 +75,14 @@ export function describeAztecMap(
|
|
|
77
75
|
await map.set('foo', 'bar');
|
|
78
76
|
await map.set('foo', 'baz');
|
|
79
77
|
|
|
80
|
-
expect(await get('foo')).
|
|
78
|
+
expect(await get('foo')).toBe('baz');
|
|
81
79
|
});
|
|
82
80
|
|
|
83
81
|
it('should be able to set values if they do not exist', async () => {
|
|
84
|
-
expect(await map.setIfNotExists('foo', 'bar')).
|
|
85
|
-
expect(await map.setIfNotExists('foo', 'baz')).
|
|
82
|
+
expect(await map.setIfNotExists('foo', 'bar')).toBe(true);
|
|
83
|
+
expect(await map.setIfNotExists('foo', 'baz')).toBe(false);
|
|
86
84
|
|
|
87
|
-
expect(await get('foo')).
|
|
85
|
+
expect(await get('foo')).toBe('bar');
|
|
88
86
|
});
|
|
89
87
|
|
|
90
88
|
it('should be able to delete values', async () => {
|
|
@@ -93,56 +91,56 @@ export function describeAztecMap(
|
|
|
93
91
|
|
|
94
92
|
await map.delete('foo');
|
|
95
93
|
|
|
96
|
-
expect(await get('foo')).
|
|
97
|
-
expect(await get('baz')).
|
|
94
|
+
expect(await get('foo')).toBe(undefined);
|
|
95
|
+
expect(await get('baz')).toBe('qux');
|
|
98
96
|
});
|
|
99
97
|
|
|
100
98
|
it('should be able to return size of the map', async () => {
|
|
101
99
|
await map.set('foo', 'bar');
|
|
102
|
-
expect(await size()).
|
|
100
|
+
expect(await size()).toBe(1);
|
|
103
101
|
await map.set('baz', 'qux');
|
|
104
|
-
expect(await size()).
|
|
102
|
+
expect(await size()).toBe(2);
|
|
105
103
|
|
|
106
104
|
await map.delete('foo');
|
|
107
|
-
expect(await size()).
|
|
105
|
+
expect(await size()).toBe(1);
|
|
108
106
|
});
|
|
109
107
|
|
|
110
108
|
it('returns 0 for empty map size', async () => {
|
|
111
|
-
expect(await size()).
|
|
109
|
+
expect(await size()).toBe(0);
|
|
112
110
|
});
|
|
113
111
|
|
|
114
112
|
it('calculates size correctly across multiple operations', async () => {
|
|
115
|
-
expect(await size()).
|
|
113
|
+
expect(await size()).toBe(0);
|
|
116
114
|
|
|
117
115
|
// Add items
|
|
118
116
|
await map.set('a', 'value1');
|
|
119
117
|
await map.set('b', 'value2');
|
|
120
118
|
await map.set('c', 'value3');
|
|
121
|
-
expect(await size()).
|
|
119
|
+
expect(await size()).toBe(3);
|
|
122
120
|
|
|
123
121
|
// Update existing (size should not change)
|
|
124
122
|
await map.set('b', 'updated');
|
|
125
|
-
expect(await size()).
|
|
123
|
+
expect(await size()).toBe(3);
|
|
126
124
|
|
|
127
125
|
// Delete some
|
|
128
126
|
await map.delete('a');
|
|
129
|
-
expect(await size()).
|
|
127
|
+
expect(await size()).toBe(2);
|
|
130
128
|
|
|
131
129
|
// Delete all
|
|
132
130
|
await map.delete('b');
|
|
133
131
|
await map.delete('c');
|
|
134
|
-
expect(await size()).
|
|
132
|
+
expect(await size()).toBe(0);
|
|
135
133
|
});
|
|
136
134
|
|
|
137
135
|
it('should be able to iterate over entries when there are no keys', async () => {
|
|
138
|
-
expect(await entries()).
|
|
136
|
+
expect(await entries()).toEqual([]);
|
|
139
137
|
});
|
|
140
138
|
|
|
141
139
|
it('should be able to iterate over entries', async () => {
|
|
142
140
|
await map.set('foo', 'bar');
|
|
143
141
|
await map.set('baz', 'qux');
|
|
144
142
|
|
|
145
|
-
expect(await entries()).
|
|
143
|
+
expect(await entries()).toEqual([
|
|
146
144
|
['baz', 'qux'],
|
|
147
145
|
['foo', 'bar'],
|
|
148
146
|
]);
|
|
@@ -152,21 +150,21 @@ export function describeAztecMap(
|
|
|
152
150
|
await map.set('foo', 'bar');
|
|
153
151
|
await map.set('baz', 'quux');
|
|
154
152
|
|
|
155
|
-
expect(await values()).
|
|
153
|
+
expect(await values()).toEqual(['quux', 'bar']);
|
|
156
154
|
});
|
|
157
155
|
|
|
158
156
|
it('should be able to iterate over keys', async () => {
|
|
159
157
|
await map.set('foo', 'bar');
|
|
160
158
|
await map.set('baz', 'qux');
|
|
161
159
|
|
|
162
|
-
expect(await keys()).
|
|
160
|
+
expect(await keys()).toEqual(['baz', 'foo']);
|
|
163
161
|
});
|
|
164
162
|
|
|
165
163
|
it('should be able to iterate over string keys that represent numbers', async () => {
|
|
166
164
|
await map.set('0x22', 'bar');
|
|
167
165
|
await map.set('0x31', 'qux');
|
|
168
166
|
|
|
169
|
-
expect(await keys()).
|
|
167
|
+
expect(await keys()).toEqual(['0x22', '0x31']);
|
|
170
168
|
});
|
|
171
169
|
|
|
172
170
|
for (const [name, data] of [
|
|
@@ -186,14 +184,14 @@ export function describeAztecMap(
|
|
|
186
184
|
await map.set(c, 'c');
|
|
187
185
|
await map.set(d, 'd');
|
|
188
186
|
|
|
189
|
-
expect(await keys()).
|
|
190
|
-
expect(await keys({ start: b, end: c })).
|
|
191
|
-
expect(await keys({ start: b })).
|
|
192
|
-
expect(await keys({ end: c })).
|
|
193
|
-
expect(await keys({ start: b, end: c, reverse: true })).
|
|
194
|
-
expect(await keys({ start: b, limit: 1 })).
|
|
195
|
-
expect(await keys({ start: b, reverse: true })).
|
|
196
|
-
expect(await keys({ end: b, reverse: true })).
|
|
187
|
+
expect(await keys()).toEqual([a, b, c, d]);
|
|
188
|
+
expect(await keys({ start: b, end: c })).toEqual([b]);
|
|
189
|
+
expect(await keys({ start: b })).toEqual([b, c, d]);
|
|
190
|
+
expect(await keys({ end: c })).toEqual([a, b]);
|
|
191
|
+
expect(await keys({ start: b, end: c, reverse: true })).toEqual([c]);
|
|
192
|
+
expect(await keys({ start: b, limit: 1 })).toEqual([b]);
|
|
193
|
+
expect(await keys({ start: b, reverse: true })).toEqual([d, c]);
|
|
194
|
+
expect(await keys({ end: b, reverse: true })).toEqual([b, a]);
|
|
197
195
|
});
|
|
198
196
|
}
|
|
199
197
|
});
|