Skip to content

Commit

Permalink
Initial mem store.
Browse files Browse the repository at this point in the history
  • Loading branch information
charlielye committed Mar 30, 2024
1 parent eb35c20 commit 60a3e99
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 95 deletions.
11 changes: 6 additions & 5 deletions yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { AztecAddress } from '@aztec/foundation/aztec-address';
import { createDebugLogger } from '@aztec/foundation/log';
import { type AztecKVStore } from '@aztec/kv-store';
import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
import { AztecMemStore } from '@aztec/kv-store/mem';
import { initStoreForRollup, openTmpStore } from '@aztec/kv-store/utils';
import { SHA256Trunc, StandardTree } from '@aztec/merkle-tree';
import { AztecKVTxPool, type P2P, createP2PClient } from '@aztec/p2p';
Expand Down Expand Up @@ -119,11 +120,11 @@ export class AztecNodeService implements AztecNode {

const log = createDebugLogger('aztec:node');
const storeLog = createDebugLogger('aztec:node:lmdb');
const store = await initStoreForRollup(
AztecLmdbStore.open(config.dataDirectory, false, storeLog),
config.l1Contracts.rollupAddress,
storeLog,
);
const storeDb = config.dataDirectory
? AztecLmdbStore.open(config.dataDirectory, false, storeLog)
: new AztecMemStore();

const store = await initStoreForRollup(storeDb, config.l1Contracts.rollupAddress, storeLog);

let archiver: ArchiveSource;
if (!config.archiverUrl) {
Expand Down
12 changes: 6 additions & 6 deletions yarn-project/aztec/src/cli/cmds/start_archiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import {
createArchiverRpcServer,
getConfigEnvVars as getArchiverConfigEnvVars,
} from '@aztec/archiver';
import { createDebugLogger } from '@aztec/aztec.js';
import { type ServerList } from '@aztec/foundation/json-rpc/server';
import { createDebugLogger } from '@aztec/foundation/log';
import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
import { AztecMemStore } from '@aztec/kv-store/mem';
import { initStoreForRollup } from '@aztec/kv-store/utils';

import { mergeEnvVarsAndCliOptions, parseModuleOptions } from '../util.js';
Expand All @@ -23,11 +24,10 @@ export const startArchiver = async (options: any, signalHandlers: (() => Promise
const archiverConfig = mergeEnvVarsAndCliOptions<ArchiverConfig>(archiverConfigEnvVars, archiverCliOptions, true);

const storeLog = createDebugLogger('aztec:archiver:lmdb');
const store = await initStoreForRollup(
AztecLmdbStore.open(archiverConfig.dataDirectory, false, storeLog),
archiverConfig.l1Contracts.rollupAddress,
storeLog,
);
const storeDb = archiverConfig.dataDirectory
? AztecLmdbStore.open(archiverConfig.dataDirectory, false, storeLog)
: new AztecMemStore();
const store = await initStoreForRollup(storeDb, archiverConfig.l1Contracts.rollupAddress, storeLog);
const archiverStore = new KVArchiverDataStore(store, archiverConfig.maxLogs);

const archiver = await Archiver.createAndSync(archiverConfig, archiverStore, true);
Expand Down
6 changes: 6 additions & 0 deletions yarn-project/kv-store/src/lmdb/store.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { addStoreTests } from '../tests/aztec_store_tests.js';
import { AztecLmdbStore } from './store.js';

describe('AztecLmdbStore', () => {
addStoreTests(() => AztecLmdbStore.open());
});
6 changes: 4 additions & 2 deletions yarn-project/kv-store/src/mem/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,13 @@ export class MemAztecArray<T> implements AztecArray<T> {
}

entries(): IterableIterator<[number, T]> {
return this.db.get(this.slot)?.entries() || [];
const arr = this.db.get(this.slot) || [];
return arr.entries();
}

values(): IterableIterator<T> {
return this.db.get(this.slot)?.values() || [];
const arr = this.db.get(this.slot) || [];
return arr.values();
}

[Symbol.iterator](): IterableIterator<T> {
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/kv-store/src/mem/counter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export class MemAztecCounter implements AztecCounter<Key> {
private map: MemAztecMap<number>;

constructor(name: string, db: MemDb) {
this.map = new MemAztecMap(name, db);
this.map = new MemAztecMap(name, db, false);
}

async set(key: Key, value: number): Promise<boolean> {
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/kv-store/src/mem/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ function compareKeys(a: Key, b: Key) {
* A map backed by mem.
*/
export class MemAztecMap<V> implements AztecMultiMap<Key, V> {
constructor(private name: string, private db: MemDb) {}
constructor(private name: string, private db: MemDb, private allowDups = true) {}

close(): Promise<void> {
return Promise.resolve();
}

get(key: Key): V | undefined {
const r = this.db.get(this.slot(key));
return r ? r[r.length - 1] : undefined;
return r ? r[0] : undefined;
}

getValues(key: Key): IterableIterator<V> {
Expand All @@ -54,7 +54,7 @@ export class MemAztecMap<V> implements AztecMultiMap<Key, V> {

set(key: Key, val: V): Promise<boolean> {
const r = this.db.get(this.slot(key));
if (r) {
if (r && this.allowDups) {
this.db.set(this.slot(key), [...r, val]);
} else {
this.db.set(this.slot(key), [val]);
Expand Down
64 changes: 2 additions & 62 deletions yarn-project/kv-store/src/mem/store.test.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,6 @@
import type { AztecArray, AztecCounter, AztecMap, AztecSingleton } from '../interfaces/index.js';
import { addStoreTests } from '../tests/aztec_store_tests.js';
import { AztecMemStore } from './store.js';

describe('AztecMemStore', () => {
let store: AztecMemStore;
let array: AztecArray<number>;
let multimap: AztecMap<string, number>;
let counter: AztecCounter;
let singleton: AztecSingleton<number>;

beforeEach(async () => {
store = new AztecMemStore();

array = store.openArray('test-array');
multimap = store.openMultiMap('test-multimap');
counter = store.openCounter('test-counter');
singleton = store.openSingleton('test-singleton');

await array.push(1, 2, 3);
await multimap.set('key-1', 1);
await multimap.set('key-2', 2);
await counter.set('counter-1', 3);
await singleton.set(4);
});

it('check initial state', () => {
expect(array.at(2)).toBe(3);
expect(multimap.get('key-2')).toBe(2);
expect(counter.get('counter-1')).toBe(3);
expect(singleton.get()).toBe(4);
});

it('state should update with successful tx', async () => {
await store.transaction(() => {
void array.setAt(2, 10);
void multimap.set('key-2', 20);
void counter.set('counter-1', 30);
void singleton.set(40);
});
void multimap.set('key-2', 20);

expect(array.at(2)).toBe(10);
expect(multimap.get('key-2')).toBe(20);
expect(counter.get('counter-1')).toBe(30);
expect(singleton.get()).toBe(40);
});

it('state should rollback with unsuccessful tx', async () => {
try {
await store.transaction(() => {
void array.setAt(2, 10);
void multimap.set('key-2', 20);
void counter.set('counter-1', 30);
void singleton.set(40);
throw new Error();
});
} catch (err) {
// swallow
}

expect(array.at(2)).toBe(3);
expect(multimap.get('key-2')).toBe(2);
expect(counter.get('counter-1')).toBe(3);
expect(singleton.get()).toBe(4);
});
addStoreTests(() => new AztecMemStore());
});
4 changes: 2 additions & 2 deletions yarn-project/kv-store/src/mem/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ export class AztecMemStore implements AztecKVStore {
private data = new MemDb();

openMap<K extends string | number, V>(name: string): AztecMap<K, V> {
return new MemAztecMap(name, this.data) as any;
return new MemAztecMap(name, this.data, false) as any;
}

openMultiMap<K extends string | number, V>(name: string): AztecMultiMap<K, V> {
return new MemAztecMap(name, this.data) as any;
return new MemAztecMap(name, this.data, true) as any;
}

openCounter<K extends string | number | Array<string | number>>(name: string): AztecCounter<K> {
Expand Down
1 change: 1 addition & 0 deletions yarn-project/kv-store/src/tests/aztec_array_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export function addArrayTests(getArray: () => AztecArray<number>) {
expect(await arr.pop()).toEqual(2);
expect(await arr.pop()).toEqual(1);
expect(await arr.pop()).toEqual(undefined);
expect(Array.from(arr)).toEqual([1, 2, 3]);
});

it('should be able to get values by index', async () => {
Expand Down
10 changes: 2 additions & 8 deletions yarn-project/kv-store/src/tests/aztec_map_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,6 @@ export function addMapTests(get: () => AztecMultiMap<Key, string>) {
expect(map.get('quux')).toEqual(undefined);
});

it('should be able to update values', async () => {
await map.set('foo', 'bar');
expect(map.get('foo')).toEqual('bar');

await map.set('foo', 'qux');
expect(map.get('foo')).toEqual('qux');
});

it('should be able to set values if they do not exist', async () => {
expect(await map.setIfNotExists('foo', 'bar')).toEqual(true);
expect(await map.setIfNotExists('foo', 'baz')).toEqual(false);
Expand Down Expand Up @@ -73,6 +65,8 @@ export function addMapTests(get: () => AztecMultiMap<Key, string>) {
await map.set('foo', 'bar');
await map.set('foo', 'baz');

expect(map.get('foo')).toEqual('bar');

expect([...map.getValues('foo')]).toEqual(['bar', 'baz']);
});

Expand Down
71 changes: 71 additions & 0 deletions yarn-project/kv-store/src/tests/aztec_store_tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { beforeEach, describe, expect, it } from '@jest/globals';

import type { AztecArray, AztecCounter, AztecKVStore, AztecMultiMap, AztecSingleton } from '../interfaces/index.js';

export function addStoreTests(get: () => AztecKVStore) {
describe('AztecStore', () => {
let store: AztecKVStore;
let array: AztecArray<number>;
let multimap: AztecMultiMap<string, number>;
let counter: AztecCounter;
let singleton: AztecSingleton<number>;

beforeEach(async () => {
store = get();

array = store.openArray('test-array');
multimap = store.openMultiMap('test-multimap');
counter = store.openCounter('test-counter');
singleton = store.openSingleton('test-singleton');

await array.push(1, 2, 3);
await multimap.set('key-1', 1);
await multimap.set('key-2', 2);
await counter.set('counter-1', 3);
await singleton.set(4);
});

it('check initial state', () => {
expect(array.at(2)).toBe(3);
expect(multimap.get('key-2')).toBe(2);
expect([...multimap.getValues('key-2')]).toEqual([2]);
expect(counter.get('counter-1')).toBe(3);
expect(singleton.get()).toBe(4);
});

it('state should update with successful tx', async () => {
await store.transaction(() => {
void array.setAt(2, 10);
void multimap.set('key-2', 20);
void counter.set('counter-1', 30);
void singleton.set(40);
});

expect(array.at(2)).toBe(10);
expect(multimap.get('key-2')).toBe(2);
expect([...multimap.getValues('key-2')]).toEqual([2, 20]);
expect(counter.get('counter-1')).toBe(30);
expect(singleton.get()).toBe(40);
});

it.skip('state should rollback with unsuccessful tx', async () => {
try {
await store.transaction(() => {
void array.setAt(2, 10);
void multimap.set('key-2', 20);
void counter.set('counter-1', 30);
void singleton.set(40);
throw new Error();
});
} catch (err) {
// swallow
}

expect(array.at(2)).toBe(3);
expect(multimap.get('key-2')).toBe(2);
expect([...multimap.getValues('key-2')]).toEqual([2]);
expect(counter.get('counter-1')).toBe(3);
expect(singleton.get()).toBe(4);
});
});
}
1 change: 0 additions & 1 deletion yarn-project/kv-store/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,4 @@ export async function initStoreForRollup<T extends AztecKVStore>(
*/
export function openTmpStore(ephemeral: boolean = false): AztecKVStore {
return new AztecMemStore();
// return AztecLmdbStore.open(undefined, ephemeral);
}
11 changes: 6 additions & 5 deletions yarn-project/pxe/src/pxe_service/create_pxe_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Grumpkin } from '@aztec/circuits.js/barretenberg';
import { randomBytes } from '@aztec/foundation/crypto';
import { TestKeyStore } from '@aztec/key-store';
import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
import { AztecMemStore } from '@aztec/kv-store/mem';
import { initStoreForRollup } from '@aztec/kv-store/utils';
import { getCanonicalClassRegisterer } from '@aztec/protocol-contracts/class-registerer';
import { getCanonicalGasToken } from '@aztec/protocol-contracts/gas-token';
Expand Down Expand Up @@ -37,11 +38,11 @@ export async function createPXEService(
const keyStorePath = config.dataDirectory ? join(config.dataDirectory, 'pxe_key_store') : undefined;
const l1Contracts = await aztecNode.getL1ContractAddresses();

const keyStore = new TestKeyStore(
new Grumpkin(),
await initStoreForRollup(AztecLmdbStore.open(keyStorePath), l1Contracts.rollupAddress),
);
const db = new KVPxeDatabase(await initStoreForRollup(AztecLmdbStore.open(pxeDbPath), l1Contracts.rollupAddress));
const keyStoreDb = keyStorePath ? AztecLmdbStore.open(keyStorePath) : new AztecMemStore();
const pxeDb = pxeDbPath ? AztecLmdbStore.open(pxeDbPath) : new AztecMemStore();

const keyStore = new TestKeyStore(new Grumpkin(), await initStoreForRollup(keyStoreDb, l1Contracts.rollupAddress));
const db = new KVPxeDatabase(await initStoreForRollup(pxeDb, l1Contracts.rollupAddress));

const server = new PXEService(keyStore, aztecNode, db, config, logSuffix);
for (const contract of [
Expand Down

0 comments on commit 60a3e99

Please sign in to comment.