Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: lift rollup address check & deplot kv-store to npm #4483

Merged
merged 6 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { AztecLmdbStore } from '@aztec/kv-store';
import { openTmpStore } from '@aztec/kv-store/utils';

import { describeArchiverDataStore } from '../archiver_store_test_suite.js';
import { KVArchiverDataStore } from './kv_archiver_store.js';

describe('KVArchiverDataStore', () => {
let archiverStore: KVArchiverDataStore;

beforeEach(async () => {
archiverStore = new KVArchiverDataStore(await AztecLmdbStore.openTmp());
beforeEach(() => {
archiverStore = new KVArchiverDataStore(openTmpStore());
});

describeArchiverDataStore('ArchiverStore', () => archiverStore);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class KVArchiverDataStore implements ArchiverDataStore {
#contractClassStore: ContractClassStore;
#contractInstanceStore: ContractInstanceStore;

#log = createDebugLogger('aztec:archiver:lmdb');
#log = createDebugLogger('aztec:archiver:data-store');

constructor(db: AztecKVStore, logsMaxPageSize: number = 1000) {
this.#blockStore = new BlockStore(db);
Expand Down
11 changes: 9 additions & 2 deletions yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ import { computePublicDataTreeLeafSlot } from '@aztec/circuits.js/abis';
import { L1ContractAddresses, createEthereumChain } from '@aztec/ethereum';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { createDebugLogger } from '@aztec/foundation/log';
import { AztecKVStore, AztecLmdbStore } from '@aztec/kv-store';
import { AztecKVStore } from '@aztec/kv-store';
import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
import { initStoreForRollup } from '@aztec/kv-store/utils';
import { AztecKVTxPool, P2P, createP2PClient } from '@aztec/p2p';
import {
GlobalVariableBuilder,
Expand Down Expand Up @@ -104,7 +106,12 @@ export class AztecNodeService implements AztecNode {
}

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

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

import { mergeEnvVarsAndCliOptions, parseModuleOptions } from '../util.js';

Expand All @@ -20,7 +22,12 @@ export const startArchiver = async (options: any, signalHandlers: (() => Promise
// merge env vars and cli options
const archiverConfig = mergeEnvVarsAndCliOptions<ArchiverConfig>(archiverConfigEnvVars, archiverCliOptions, true);

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

const archiver = await Archiver.createAndSync(archiverConfig, archiverStore, true);
Expand Down
1 change: 1 addition & 0 deletions yarn-project/deploy_npm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ deploy_package l1-artifacts
deploy_package ethereum
deploy_package noir-compiler
deploy_package noir-contracts
deploy_package kv-store
deploy_package merkle-tree
deploy_package noir-protocol-circuits
deploy_package simulator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
computeAuthWitMessageHash,
computeMessageSecretHash,
} from '@aztec/aztec.js';
import { AztecLmdbStore } from '@aztec/kv-store';
import { openTmpStore } from '@aztec/kv-store/utils';
import { Pedersen, SparseTree, newTree } from '@aztec/merkle-tree';
import { SlowTreeContract, TokenBlacklistContract, TokenContract } from '@aztec/noir-contracts';

Expand Down Expand Up @@ -104,7 +104,7 @@ describe('e2e_blacklist_token_contract', () => {
slowTree = await SlowTreeContract.deploy(wallets[0]).send().deployed();

const depth = 254;
slowUpdateTreeSimulator = await newTree(SparseTree, await AztecLmdbStore.openTmp(), new Pedersen(), 'test', depth);
slowUpdateTreeSimulator = await newTree(SparseTree, openTmpStore(), new Pedersen(), 'test', depth);

const deployTx = TokenBlacklistContract.deploy(wallets[0], accounts[0], slowTree.address).send({});
const receipt = await deployTx.wait();
Expand Down
10 changes: 2 additions & 8 deletions yarn-project/end-to-end/src/e2e_slow_tree.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable camelcase */
import { CheatCodes, DebugLogger, Fr, Wallet } from '@aztec/aztec.js';
import { AztecLmdbStore } from '@aztec/kv-store';
import { openTmpStore } from '@aztec/kv-store/utils';
import { Pedersen, SparseTree, newTree } from '@aztec/merkle-tree';
import { SlowTreeContract } from '@aztec/noir-contracts/SlowTree';

Expand All @@ -23,13 +23,7 @@ describe('e2e_slow_tree', () => {

it('Messing around with noir slow tree', async () => {
const depth = 254;
const slowUpdateTreeSimulator = await newTree(
SparseTree,
await AztecLmdbStore.openTmp(),
new Pedersen(),
'test',
depth,
);
const slowUpdateTreeSimulator = await newTree(SparseTree, openTmpStore(), new Pedersen(), 'test', depth);
const getMembershipProof = async (index: bigint, includeUncommitted: boolean) => {
return {
index,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
Wallet,
computeMessageSecretHash,
} from '@aztec/aztec.js';
import { AztecLmdbStore } from '@aztec/kv-store';
import { initStoreForRollup, openTmpStore } from '@aztec/kv-store/utils';
import { TokenContract } from '@aztec/noir-contracts/Token';

import { Chain, HttpTransport, PublicClient } from 'viem';
Expand Down Expand Up @@ -43,7 +43,9 @@ describe('archiver integration with l1 to l2 messages', () => {
config.archiverPollingIntervalMS = 100;
archiver = await Archiver.createAndSync(
{ ...config, l1Contracts: deployL1ContractsValues.l1ContractAddresses },
new KVArchiverDataStore(await AztecLmdbStore.open(deployL1ContractsValues.l1ContractAddresses.rollupAddress)),
new KVArchiverDataStore(
await initStoreForRollup(openTmpStore(), deployL1ContractsValues.l1ContractAddresses.rollupAddress),
),
);

const walletClient = deployL1ContractsValues.walletClient;
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/end-to-end/src/integration_l1_publisher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
} from '@aztec/circuits.js/factories';
import { createEthereumChain } from '@aztec/ethereum';
import { makeTuple, range } from '@aztec/foundation/array';
import { AztecLmdbStore } from '@aztec/kv-store';
import { openTmpStore } from '@aztec/kv-store/utils';
import { InboxAbi, OutboxAbi, RollupAbi } from '@aztec/l1-artifacts';
import {
EmptyRollupProver,
Expand Down Expand Up @@ -136,7 +136,7 @@ describe('L1Publisher integration', () => {
publicClient,
});

builderDb = await MerkleTrees.new(await AztecLmdbStore.openTmp()).then(t => t.asLatest());
builderDb = await MerkleTrees.new(openTmpStore()).then(t => t.asLatest());
const vks = getVerificationKeys();
const simulator = new RealRollupCircuitSimulator();
const prover = new EmptyRollupProver();
Expand Down
7 changes: 5 additions & 2 deletions yarn-project/kv-store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
"name": "@aztec/kv-store",
"version": "0.1.0",
"type": "module",
"exports": "./dest/index.js",
"exports": {
".": "./dest/interfaces/index.js",
"./lmdb": "./dest/lmdb/index.js",
"./utils": "./dest/utils.js"
},
"scripts": {
"build": "yarn clean && tsc -b",
"build:dev": "tsc -b --watch",
Expand Down Expand Up @@ -43,7 +47,6 @@
"src",
"!*.test.*"
],
"types": "./dest/index.d.ts",
"engines": {
"node": ">=18"
}
Expand Down
7 changes: 0 additions & 7 deletions yarn-project/kv-store/src/index.ts

This file was deleted.

6 changes: 6 additions & 0 deletions yarn-project/kv-store/src/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export * from './array.js';
export * from './map.js';
export * from './counter.js';
export * from './singleton.js';
export * from './store.js';
export { Range } from './common.js';
5 changes: 5 additions & 0 deletions yarn-project/kv-store/src/interfaces/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,9 @@ export interface AztecKVStore {
* @param callback - The callback to execute in a transaction
*/
transaction<T extends Exclude<any, Promise<any>>>(callback: () => T): Promise<T>;

/**
* Clears the store
*/
clear(): Promise<void>;
}
1 change: 1 addition & 0 deletions yarn-project/kv-store/src/lmdb/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { AztecLmdbStore } from './store.js';
49 changes: 10 additions & 39 deletions yarn-project/kv-store/src/lmdb/store.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { EthAddress } from '@aztec/foundation/eth-address';
import { Logger, createDebugLogger } from '@aztec/foundation/log';
import { createDebugLogger } from '@aztec/foundation/log';

import { Database, Key, RootDatabase, open } from 'lmdb';

Expand All @@ -20,12 +19,9 @@ export class AztecLmdbStore implements AztecKVStore {
#rootDb: RootDatabase;
#data: Database<unknown, Key>;
#multiMapData: Database<unknown, Key>;
#rollupAddress: AztecSingleton<string>;
#log: Logger;

constructor(rootDb: RootDatabase, log: Logger) {
constructor(rootDb: RootDatabase) {
this.#rootDb = rootDb;
this.#log = log;

// big bucket to store all the data
this.#data = rootDb.openDB('data', {
Expand All @@ -38,8 +34,6 @@ export class AztecLmdbStore implements AztecKVStore {
keyEncoding: 'ordered-binary',
dupSort: true,
});

this.#rollupAddress = this.openSingleton('rollupAddress');
}

/**
Expand All @@ -50,30 +44,14 @@ export class AztecLmdbStore implements AztecKVStore {
* the database is cleared before returning the store. This way data is not accidentally shared between
* different rollup instances.
*
* @param rollupAddress - The ETH address of the rollup contract
* @param path - A path on the disk to store the database. Optional
* @param log - A logger to use. Optional
* @returns The store
*/
static async open(
rollupAddress: EthAddress,
path?: string,
log = createDebugLogger('aztec:kv-store:lmdb'),
): Promise<AztecLmdbStore> {
static open(path?: string, log = createDebugLogger('aztec:kv-store:lmdb')): AztecLmdbStore {
log.info(`Opening LMDB database at ${path || 'temporary location'}`);

const rootDb = open({
path,
});

const db = new AztecLmdbStore(rootDb, log);
await db.#init(rollupAddress);

return db;
}

static openTmp(): Promise<AztecLmdbStore> {
return AztecLmdbStore.open(EthAddress.random());
const rootDb = open({ path });
return new AztecLmdbStore(rootDb);
}

/**
Expand Down Expand Up @@ -125,17 +103,10 @@ export class AztecLmdbStore implements AztecKVStore {
return this.#rootDb.transaction(callback);
}

async #init(rollupAddress: EthAddress): Promise<void> {
const storedRollupAddress = this.#rollupAddress.get();
const rollupAddressString = rollupAddress.toString();

if (typeof storedRollupAddress === 'string' && rollupAddressString !== storedRollupAddress) {
this.#log.warn(
`Rollup address mismatch: expected ${rollupAddress}, found ${storedRollupAddress}. Clearing entire database...`,
);
await this.#rootDb.clearAsync();
}

await this.#rollupAddress.set(rollupAddressString);
/**
* Clears the store
*/
async clear() {
await this.#rootDb.clearAsync();
}
}
41 changes: 41 additions & 0 deletions yarn-project/kv-store/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { EthAddress } from '@aztec/foundation/eth-address';
import { Logger } from '@aztec/foundation/log';

import { AztecKVStore } from './interfaces/store.js';
import { AztecLmdbStore } from './lmdb/store.js';

/**
* Clears the store if the rollup address does not match the one stored in the database.
* This is to prevent data from being accidentally shared between different rollup instances.
* @param store - The store to check
* @param rollupAddress - The ETH address of the rollup contract
* @returns A promise that resolves when the store is cleared, or rejects if the rollup address does not match
*/
export async function initStoreForRollup<T extends AztecKVStore>(
store: T,
rollupAddress: EthAddress,
log?: Logger,
): Promise<T> {
const rollupAddressValue = store.openSingleton<ReturnType<EthAddress['toString']>>('rollupAddress');
const rollupAddressString = rollupAddress.toString();
const storedRollupAddressString = rollupAddressValue.get();

if (typeof storedRollupAddressString !== 'undefined' && storedRollupAddressString !== rollupAddressString) {
log?.warn(
`Rollup address mismatch: expected ${rollupAddress}, found ${rollupAddressValue}. Clearing entire database...`,
);

await store.clear();
}

await rollupAddressValue.set(rollupAddressString);
return store;
}

/**
* Opens a temporary store for testing purposes.
* @returns A new store
*/
export function openTmpStore(): AztecKVStore {
return AztecLmdbStore.open();
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AztecKVStore, AztecLmdbStore } from '@aztec/kv-store';
import { AztecKVStore } from '@aztec/kv-store';
import { openTmpStore } from '@aztec/kv-store/utils';

import { Pedersen, StandardTree, newTree } from '../index.js';
import { AppendOnlySnapshotBuilder } from './append_only_snapshot.js';
Expand All @@ -10,7 +11,7 @@ describe('AppendOnlySnapshot', () => {
let db: AztecKVStore;

beforeEach(async () => {
db = await AztecLmdbStore.openTmp();
db = openTmpStore();
const hasher = new Pedersen();
tree = await newTree(StandardTree, db, hasher, 'test', 4);
snapshotBuilder = new AppendOnlySnapshotBuilder(db, tree, hasher);
Expand Down
5 changes: 3 additions & 2 deletions yarn-project/merkle-tree/src/snapshots/full_snapshot.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AztecKVStore, AztecLmdbStore } from '@aztec/kv-store';
import { AztecKVStore } from '@aztec/kv-store';
import { openTmpStore } from '@aztec/kv-store/utils';

import { Pedersen, StandardTree, newTree } from '../index.js';
import { FullTreeSnapshotBuilder } from './full_snapshot.js';
Expand All @@ -10,7 +11,7 @@ describe('FullSnapshotBuilder', () => {
let db: AztecKVStore;

beforeEach(async () => {
db = await AztecLmdbStore.openTmp();
db = openTmpStore();
tree = await newTree(StandardTree, db, new Pedersen(), 'test', 4);
snapshotBuilder = new FullTreeSnapshotBuilder(db, tree);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Fr, NullifierLeaf, NullifierLeafPreimage } from '@aztec/circuits.js';
import { AztecKVStore, AztecLmdbStore } from '@aztec/kv-store';
import { AztecKVStore } from '@aztec/kv-store';
import { openTmpStore } from '@aztec/kv-store/utils';
import { Hasher } from '@aztec/types/interfaces';

import { Pedersen, newTree } from '../index.js';
Expand All @@ -19,7 +20,7 @@ describe('IndexedTreeSnapshotBuilder', () => {
let snapshotBuilder: IndexedTreeSnapshotBuilder;

beforeEach(async () => {
db = await AztecLmdbStore.openTmp();
db = openTmpStore();
tree = await newTree(NullifierTree, db, new Pedersen(), 'test', 4);
snapshotBuilder = new IndexedTreeSnapshotBuilder(db, tree, NullifierLeafPreimage);
});
Expand Down
Loading
Loading