Skip to content
This repository was archived by the owner on Jun 29, 2023. It is now read-only.

Commit cd69254

Browse files
committed
parameterized database and updated storage consumers
1 parent c1d1f19 commit cd69254

20 files changed

+221
-86
lines changed

test/client/integration.test.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ import { CustomToken__factory } from "../../types/ethers-contracts";
2929
*/
3030
describe("Client Integration", function() {
3131
before(async function() {
32-
await del("./leveldb/*");
32+
await del("./leveldb/test/syncer/*");
33+
await del("./leveldb/test/packer/*");
3334
});
3435

3536
after(async function() {
36-
await del("./leveldb/*");
37+
await del("./leveldb/test/syncer/*");
38+
await del("./leveldb/test/packer/*");
3739
});
3840

3941
it("run", async function() {
@@ -47,8 +49,12 @@ describe("Client Integration", function() {
4749

4850
await deployKeyless(signer, false);
4951

50-
const storageSyncer = await storageManagerFactory();
51-
const storagePacker = await storageManagerFactory();
52+
const storageSyncer = await storageManagerFactory({
53+
storageDirectory: "./levelDB/test/syncer"
54+
});
55+
const storagePacker = await storageManagerFactory({
56+
storageDirectory: "./levelDB/test/packer"
57+
});
5258

5359
// Ensure initial states match
5460
assert.equal(storageSyncer.state.root, storagePacker.state.root);

test/client/pubkey2states.test.ts

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import chai, { assert } from "chai";
22
import chaiAsPromised from "chai-as-promised";
33
import { StateDatabaseEngine } from "../../ts/client/database";
4-
import { PRODUCTION_PARAMS } from "../../ts/constants";
4+
import { PRODUCTION_PARAMS, TESTING_PARAMS } from "../../ts/constants";
55
import { State } from "../../ts/state";
66
import del from "del";
77
import { PubkeyLeaf } from "../../ts/tree/leaves/PubkeyLeaf";
88
import { init } from "../../ts/mcl";
99
import { BlsSigner } from "../../ts/blsSigner";
1010
import { Pubkey2StatesDB } from "../../ts/client/database/pubkey2states";
11+
import { Connection } from "../../ts/client/database/connection";
1112

1213
chai.use(chaiAsPromised);
1314

@@ -22,26 +23,37 @@ describe("StateDBEngine", () => {
2223
let p1: PubkeyLeaf;
2324
let statesP0: State[];
2425
let statesP1: State[];
26+
let connection: Connection;
2527

2628
before(async function() {
27-
await del("./leveldb/*");
29+
await del("./leveldb/test/*");
30+
connection = await Connection.create(TESTING_PARAMS.STORAGE_DIRECTORY);
2831
});
2932

3033
after(async function() {
31-
await del("./leveldb/*");
34+
await connection.close();
35+
await del("./leveldb/test/*");
3236
});
3337

3438
beforeEach(async function() {
35-
engine = new StateDatabaseEngine(maxDepth);
39+
engine = new StateDatabaseEngine(maxDepth, connection);
3640
statesP0 = [];
3741
statesP1 = [];
3842

3943
await init();
4044

41-
p0 = PubkeyLeaf.fromSolG2(BlsSigner.new().pubkey, 0);
45+
p0 = PubkeyLeaf.fromSolG2(
46+
BlsSigner.new().pubkey,
47+
0,
48+
connection.pubkeyDB
49+
);
4250
await p0.toDB();
4351

44-
p1 = PubkeyLeaf.fromSolG2(BlsSigner.new().pubkey, 1);
52+
p1 = PubkeyLeaf.fromSolG2(
53+
BlsSigner.new().pubkey,
54+
1,
55+
connection.pubkeyDB
56+
);
4557
await p1.toDB();
4658

4759
for (let i = 0; i < 4; i++) {
@@ -56,15 +68,19 @@ describe("StateDBEngine", () => {
5668
await engine.updateBatch(0, maxSubtreeDepth, statesP0);
5769
await engine.updateBatch(1, maxSubtreeDepth, statesP1);
5870

59-
assert.deepEqual(await Pubkey2StatesDB.getStates(p0.item.hash()), [
60-
0,
61-
1,
62-
2,
63-
3
64-
]);
65-
assert.deepEqual(await Pubkey2StatesDB.getStates(p1.item.hash()), [
66-
4,
67-
5
68-
]);
71+
assert.deepEqual(
72+
await Pubkey2StatesDB.getStates(
73+
p0.item.hash(),
74+
connection.pubkey2statesDB
75+
),
76+
[0, 1, 2, 3]
77+
);
78+
assert.deepEqual(
79+
await Pubkey2StatesDB.getStates(
80+
p1.item.hash(),
81+
connection.pubkey2statesDB
82+
),
83+
[4, 5]
84+
);
6985
});
7086
});

test/client/transaction.test.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import chai, { assert } from "chai";
44
import chaiAsPromised from "chai-as-promised";
55
import del from "del";
66
import { BlsSigner } from "../../ts/blsSigner";
7+
import { Connection } from "../../ts/client/database/connection";
78
import { OffchainTx } from "../../ts/client/features/interface";
89
import { TransferOffchainTx } from "../../ts/client/features/transfer";
910
import { Status } from "../../ts/client/storageEngine/transactions/constants";
1011
import { TransactionDBStorage } from "../../ts/client/storageEngine/transactions/db";
12+
import { TESTING_PARAMS } from "../../ts/constants";
1113
import {
1214
StatusTransitionInvalid,
1315
TransactionAlreadyExists,
@@ -38,11 +40,18 @@ const txFactory = (
3840
};
3941

4042
describe("TransactionDBStorage", () => {
41-
let storage = new TransactionDBStorage();
43+
let connection: Connection;
44+
let storage: TransactionDBStorage;
4245

4346
before(async function() {
4447
await del("./leveldb/*");
4548
await mcl.init();
49+
connection = await Connection.create(TESTING_PARAMS.STORAGE_DIRECTORY);
50+
storage = new TransactionDBStorage(connection);
51+
});
52+
53+
after(async function() {
54+
await connection.close();
4655
});
4756

4857
describe("get", () => {

ts/client/database/connection.ts

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,41 @@
11
import level from "level";
22
import sub from "subleveldown";
3+
import { LevelUp } from "levelup";
34

4-
const db = level("./leveldb", { valueEncoding: "json" });
5+
import { mkdir, stat } from "fs";
6+
import { promisify } from "util";
57

6-
export const close = async (): Promise<void> => {
7-
await db.close();
8-
};
8+
const mkdirAsync = promisify(mkdir);
9+
const existsAsync = promisify(stat);
910

10-
export const pubkeyDB = sub(db, "pubkey");
11-
export const stateDB = sub(db, "state");
12-
export const nodeDB = sub(db, "node");
13-
// export const batchDB = sub(db, "batch");
14-
export const txDB = sub(db, "tx");
15-
export const pubkey2statesDB = sub(db, "pubkey2states");
11+
export class Connection {
12+
public readonly pubkeyDB: LevelUp;
13+
public readonly stateDB: LevelUp;
14+
public readonly txDB: LevelUp;
15+
public readonly pubkey2statesDB: LevelUp;
16+
17+
private db: LevelUp;
18+
19+
constructor(path: string) {
20+
this.db = level(`${path}`, { valueEncoding: "json" });
21+
22+
this.pubkeyDB = sub(this.db, "pubkey");
23+
this.stateDB = sub(this.db, "state");
24+
this.txDB = sub(this.db, "tx");
25+
this.pubkey2statesDB = sub(this.db, "pubkey2states");
26+
}
27+
28+
public static async create(path: string) {
29+
try {
30+
await existsAsync(path);
31+
} catch (error) {
32+
await mkdirAsync(path, { recursive: true });
33+
}
34+
35+
return new Connection(path);
36+
}
37+
38+
public async close(): Promise<void> {
39+
await this.db.close();
40+
}
41+
}

ts/client/database/databaseEngine.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@ import { Hasher } from "../../tree";
55
import { DBTree } from "../../tree/dbTree";
66
import { LeafFactoryFunc } from "../../tree/leaves/Leaf";
77
import { StorageEngine, WithWitness } from "../storageEngine/interfaces";
8+
import { LevelUp } from "levelup";
89

910
export class DatabaseEngine<Item extends Hashable>
1011
implements StorageEngine<Item> {
1112
private tree: DBTree;
1213
public readonly leafFactory: LeafFactoryFunc<Item>;
1314

14-
constructor(depth: number, factory: LeafFactoryFunc<Item>) {
15+
constructor(depth: number, db: LevelUp, factory: LeafFactoryFunc<Item>) {
1516
this.tree = DBTree.new(
1617
depth,
1718
factory.name,
19+
db,
1820
Hasher.new("bytes", ZERO_BYTES32)
1921
);
2022
this.leafFactory = factory;

ts/client/database/pubkey2states.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
import _ from "lodash";
22
import { PubkeyLeafFactory } from "../../tree/leaves/PubkeyLeaf";
3-
import { pubkey2statesDB } from "./connection";
3+
import { LevelUp } from "levelup";
44

55
export class Pubkey2StatesDB {
6-
static async getStates(pubkeyHash: string): Promise<number[]> {
6+
static async getStates(
7+
pubkeyHash: string,
8+
pubkey2statesDB: LevelUp
9+
): Promise<number[]> {
710
return JSON.parse(await pubkey2statesDB.get(pubkeyHash));
811
}
912

10-
static async update(pubkeyID: number, stateID: number): Promise<void> {
11-
const pubkeyLeaf = await PubkeyLeafFactory().fromDB(pubkeyID);
13+
static async update(
14+
pubkeyID: number,
15+
stateID: number,
16+
pubkey2statesDB: LevelUp,
17+
pubkeyDB: LevelUp
18+
): Promise<void> {
19+
const pubkeyLeaf = await PubkeyLeafFactory(pubkeyDB).fromDB(pubkeyID);
1220
const pubkeyHash = pubkeyLeaf.item.hash();
1321

1422
try {

ts/client/database/pubkeyEngine.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
import { Pubkey } from "../../pubkey";
22
import { PubkeyLeafFactory } from "../../tree/leaves/PubkeyLeaf";
33
import { StorageEngine } from "../storageEngine/interfaces";
4+
import { Connection } from "./connection";
45
import { DatabaseEngine } from "./databaseEngine";
56

67
export interface PubkeyStorageEngine extends StorageEngine<Pubkey> {}
78

89
export class PubkeyDatabaseEngine extends DatabaseEngine<Pubkey>
910
implements PubkeyStorageEngine {
10-
constructor(depth: number) {
11-
super(depth, PubkeyLeafFactory());
11+
constructor(depth: number, connections: Connection) {
12+
super(
13+
depth,
14+
connections.pubkeyDB,
15+
PubkeyLeafFactory(connections.pubkeyDB)
16+
);
1217
}
1318
}

ts/client/database/stateEngine.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
import { State } from "../../state";
22
import { StateLeafFactory } from "../../tree/leaves/StateLeaf";
33
import { StorageEngine } from "../storageEngine/interfaces";
4+
import { Connection } from "./connection";
45
import { DatabaseEngine } from "./databaseEngine";
56
import { Pubkey2StatesDB } from "./pubkey2states";
67

78
export interface StateStorageEngine extends StorageEngine<State> {}
89

910
export class StateDatabaseEngine extends DatabaseEngine<State>
1011
implements StateStorageEngine {
11-
constructor(depth: number) {
12-
super(depth, StateLeafFactory());
12+
constructor(depth: number, public readonly connections: Connection) {
13+
super(
14+
depth,
15+
connections.stateDB,
16+
StateLeafFactory(connections.stateDB)
17+
);
1318
}
1419

1520
public async updateBatch(
@@ -20,7 +25,12 @@ export class StateDatabaseEngine extends DatabaseEngine<State>
2025
for (const [i, item] of items.entries()) {
2126
const itemID = path * 2 ** depth + i;
2227
await this.update(itemID, item);
23-
await Pubkey2StatesDB.update(item.pubkeyID.toNumber(), itemID);
28+
await Pubkey2StatesDB.update(
29+
item.pubkeyID.toNumber(),
30+
itemID,
31+
this.connections.pubkey2statesDB,
32+
this.connections.pubkeyDB
33+
);
2434
}
2535
}
2636
}

ts/client/node.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { SyncCompleteEvent } from "./constants";
1515
import { ClientConfig } from "./config";
1616
import { Genesis } from "../genesis";
1717
import { EmptyConfigPropError, MissingConfigPropError } from "../exceptions";
18-
import { close as closeDB } from "./database/connection";
1918

2019
export type NodeModes = {
2120
isProposer: boolean;
@@ -45,10 +44,11 @@ export class HubbleNode {
4544
console.error(err);
4645
});
4746

48-
const { MAX_DEPTH } = genesis.parameters;
47+
const { MAX_DEPTH, STORAGE_DIRECTORY } = genesis.parameters;
4948
const storageManager = await storageManagerFactory({
5049
stateTreeDepth: MAX_DEPTH,
51-
pubkeyTreeDepth: MAX_DEPTH
50+
pubkeyTreeDepth: MAX_DEPTH,
51+
storageDirectory: STORAGE_DIRECTORY
5252
});
5353

5454
const signer = provider.getSigner();
@@ -133,7 +133,6 @@ export class HubbleNode {
133133
this.packer?.stop();
134134
this.bidder?.stop();
135135
console.log("closing leveldb connection");
136-
await closeDB();
137136
}
138137

139138
onSyncComplete = async () => {

ts/client/services/rpc.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ export class RPC {
5050
try {
5151
const { pubkeyHash } = request.params;
5252
const stateIndices = await Pubkey2StatesDB.getStates(
53-
pubkeyHash
53+
pubkeyHash,
54+
l2Storage.connection.pubkey2statesDB
5455
);
5556
let data = stateIndices.map(async id => {
5657
let state = await l2Storage.state.get(Number(id));
@@ -94,7 +95,8 @@ export class RPC {
9495
try {
9596
const { pubkeyHash } = request.params;
9697
const stateIndices = await Pubkey2StatesDB.getStates(
97-
pubkeyHash
98+
pubkeyHash,
99+
l2Storage.connection.pubkey2statesDB
98100
);
99101
let data = await l2Storage.state.get(
100102
Number(stateIndices[0])

0 commit comments

Comments
 (0)