Skip to content

Commit

Permalink
Merge pull request #1 from boray/main
Browse files Browse the repository at this point in the history
Fix ERR_MODULE_NOT_FOUND
  • Loading branch information
coldstar1993 authored Mar 10, 2024
2 parents b76ad0f + 8285a58 commit a8b4ca1
Show file tree
Hide file tree
Showing 138 changed files with 9,634 additions and 161 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@ coverage
*.log
yarn.lock
db
rocksdb

rocksdb
25 changes: 25 additions & 0 deletions build/module/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export * from './lib/smt/smt.js';
export * from './lib/smt/verify_circuit.js';
export * from './lib/smt/proofs.js';
export * from './lib/smt/deep_subtree.js';
export * from './lib/smt/deep_subtree_circuit.js';
export * from './lib/merkle/merkle_tree.js';
export * from './lib/merkle/verify_circuit.js';
export * from './lib/merkle/proofs.js';
export * from './lib/merkle/deep_subtree.js';
export * from './lib/merkle/deep_subtree_circuit.js';
export * from './lib/compact_smt/csmt.js';
export * from './lib/compact_smt/tree_hasher.js';
export * from './lib/compact_smt/proofs.js';
export * from './lib/compact_smt/deep_subtree.js';
export * from './lib/compact_smt/verify_circuit.js';
export type { Hasher } from './lib/model.js';
export { PoseidonHasherFunc } from './lib/model.js';
export * from './lib/default_nodes.js';
export * from './lib/utils.js';
export type { Store } from './lib/store/store.js';
export { MemoryStore } from './lib/store/memory_store.js';
export { LevelStore } from './lib/store/level_store.js';
export { MongoStore } from './lib/store/mongo_store.js';
export { RocksStore } from './lib/store/rocks_store.js';
export * from './lib/alternatives/index.js';
23 changes: 23 additions & 0 deletions build/module/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export * from './lib/smt/smt.js';
export * from './lib/smt/verify_circuit.js';
export * from './lib/smt/proofs.js';
export * from './lib/smt/deep_subtree.js';
export * from './lib/smt/deep_subtree_circuit.js';
export * from './lib/merkle/merkle_tree.js';
export * from './lib/merkle/verify_circuit.js';
export * from './lib/merkle/proofs.js';
export * from './lib/merkle/deep_subtree.js';
export * from './lib/merkle/deep_subtree_circuit.js';
export * from './lib/compact_smt/csmt.js';
export * from './lib/compact_smt/tree_hasher.js';
export * from './lib/compact_smt/proofs.js';
export * from './lib/compact_smt/deep_subtree.js';
export * from './lib/compact_smt/verify_circuit.js';
export { PoseidonHasherFunc } from './lib/model.js';
export * from './lib/default_nodes.js';
export * from './lib/utils.js';
export { MemoryStore } from './lib/store/memory_store.js';
export { LevelStore } from './lib/store/level_store.js';
export { MongoStore } from './lib/store/mongo_store.js';
export { RocksStore } from './lib/store/rocks_store.js';
export * from './lib/alternatives/index.js';
11 changes: 11 additions & 0 deletions build/module/lib/alternatives/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export * from './interfaces/append_only_tree.js';
export * from './interfaces/indexed_tree.js';
export * from './interfaces/merkle_tree.js';
export * from './interfaces/update_only_tree.js';
export * from './sparse_tree/sparse_tree.js';
export * from './standard_indexed_tree/standard_indexed_tree.js';
export * from './standard_tree/standard_tree.js';
export * from './types/index.js';
export { INITIAL_LEAF } from './tree_base.js';
export { newTree } from './new_tree.js';
export { loadTree } from './load_tree.js';
11 changes: 11 additions & 0 deletions build/module/lib/alternatives/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export * from './interfaces/append_only_tree.js';
export * from './interfaces/indexed_tree.js';
export * from './interfaces/merkle_tree.js';
export * from './interfaces/update_only_tree.js';
export * from './sparse_tree/sparse_tree.js';
export * from './standard_indexed_tree/standard_indexed_tree.js';
export * from './standard_tree/standard_tree.js';
export * from './types/index.js';
export { INITIAL_LEAF } from './tree_base.js';
export { newTree } from './new_tree.js';
export { loadTree } from './load_tree.js';
12 changes: 12 additions & 0 deletions build/module/lib/alternatives/interfaces/append_only_tree.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Field } from 'o1js';
import { IMerkleTree } from './merkle_tree.js';
/**
* A Merkle tree that supports only appending leaves and not updating existing leaves.
*/
export interface AppendOnlyTree extends IMerkleTree {
/**
* Appends a set of leaf values to the tree.
* @param leaves - The set of leaves to be appended.
*/
appendLeaves(leaves: Field[]): Promise<void>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
66 changes: 66 additions & 0 deletions build/module/lib/alternatives/interfaces/indexed_tree.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Field } from 'o1js';
import { BaseSiblingPath } from '../types/index.js';
import { LowLeafWitnessData } from '../standard_indexed_tree/standard_indexed_tree.js';
import { AppendOnlyTree } from './append_only_tree.js';
/**
* A leaf of a tree.
*/
export interface LeafData {
/**
* A value of the leaf.
*/
value: bigint;
/**
* An index of the next leaf.
*/
nextIndex: bigint;
/**
* A value of the next leaf.
*/
nextValue: bigint;
}
/**
* Indexed merkle tree.
*/
export interface IndexedTree extends AppendOnlyTree {
/**
* Finds the index of the largest leaf whose value is less than or equal to the provided value.
* @param newValue - The new value to be inserted into the tree.
* @param includeUncommitted - If true, the uncommitted changes are included in the search.
* @returns The found leaf index and a flag indicating if the corresponding leaf's value is equal to `newValue`.
*/
findIndexOfPreviousValue(newValue: bigint, includeUncommitted: boolean): {
/**
* The index of the found leaf.
*/
index: number;
/**
* A flag indicating if the corresponding leaf's value is equal to `newValue`.
*/
alreadyPresent: boolean;
};
/**
* Gets the latest LeafData copy.
* @param index - Index of the leaf of which to obtain the LeafData copy.
* @param includeUncommitted - If true, the uncommitted changes are included in the search.
* @returns A copy of the leaf data at the given index or undefined if the leaf was not found.
*/
getLatestLeafDataCopy(index: number, includeUncommitted: boolean): LeafData | undefined;
/**
* Exposes the underlying tree's update leaf method.
* @param leaf - The hash to set at the leaf.
* @param index - The index of the element.
*/
updateLeaf(leaf: LeafData, index: bigint): Promise<void>;
/**
* Batch insert multiple leaves into the tree.
* @param leaves - Leaves to insert into the tree.
* @param treeHeight - Height of the tree.
* @param subtreeHeight - Height of the subtree.
* @param includeUncommitted - If true, the uncommitted changes are included in the search.
*/
batchInsert(leaves: Field[], treeHeight: number, subtreeHeight: number, includeUncommitted: boolean): Promise<[
LowLeafWitnessData[],
BaseSiblingPath
] | [undefined, BaseSiblingPath]>;
}
1 change: 1 addition & 0 deletions build/module/lib/alternatives/interfaces/indexed_tree.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
46 changes: 46 additions & 0 deletions build/module/lib/alternatives/interfaces/merkle_tree.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Field } from 'o1js';
import { BaseSiblingPath } from '../types/index.js';
/**
* Defines the interface for a source of sibling paths.
*/
export interface SiblingPathSource {
/**
* Returns the sibling path for a requested leaf index.
* @param index - The index of the leaf for which a sibling path is required.
* @param includeUncommitted - Set to true to include uncommitted updates in the sibling path.
*/
getSiblingPath(index: bigint, includeUncommitted: boolean): Promise<BaseSiblingPath>;
}
/**
* Defines the interface for a Merkle tree.
*/
export interface IMerkleTree extends SiblingPathSource {
/**
* Returns the current root of the tree.
* @param includeUncommitted - Set to true to include uncommitted updates in the calculated root.
*/
getRoot(includeUncommitted: boolean): Field;
/**
* Returns the number of leaves in the tree.
* @param includeUncommitted - Set to true to include uncommitted updates in the returned value.
*/
getNumLeaves(includeUncommitted: boolean): bigint;
/**
* Commit pending updates to the tree.
*/
commit(): Promise<void>;
/**
* Returns the depth of the tree.
*/
getDepth(): number;
/**
* Rollback pending update to the tree.
*/
rollback(): Promise<void>;
/**
* Returns the value of a leaf at the specified index.
* @param index - The index of the leaf value to be returned.
* @param includeUncommitted - Set to true to include uncommitted updates in the data set.
*/
getLeafValue(index: bigint, includeUncommitted: boolean): Promise<Field | undefined>;
}
1 change: 1 addition & 0 deletions build/module/lib/alternatives/interfaces/merkle_tree.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
13 changes: 13 additions & 0 deletions build/module/lib/alternatives/interfaces/update_only_tree.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Field } from 'o1js';
import { IMerkleTree } from './merkle_tree.js';
/**
* A Merkle tree that supports updates at arbitrary indices but not appending.
*/
export interface UpdateOnlyTree extends IMerkleTree {
/**
* Updates a leaf at a given index in the tree.
* @param leaf - The leaf value to be updated.
* @param index - The leaf to be updated.
*/
updateLeaf(leaf: Field, index: bigint): Promise<void>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
13 changes: 13 additions & 0 deletions build/module/lib/alternatives/load_tree.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/// <reference types="node" />
import { Level } from 'level';
import { Hasher } from './types/index.js';
import { TreeBase } from './tree_base.js';
/**
* Creates a new tree and sets its root, depth and size based on the meta data which are associated with the name.
* @param c - The class of the tree to be instantiated.
* @param db - A database used to store the Merkle tree data.
* @param hasher - A hasher used to compute hash paths.
* @param name - Name of the tree.
* @returns The newly created tree.
*/
export declare function loadTree<T extends TreeBase>(c: new (...args: any[]) => T, db: Level<string, Buffer>, hasher: Hasher, name: string): Promise<T>;
16 changes: 16 additions & 0 deletions build/module/lib/alternatives/load_tree.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { decodeMeta } from './tree_base.js';
/**
* Creates a new tree and sets its root, depth and size based on the meta data which are associated with the name.
* @param c - The class of the tree to be instantiated.
* @param db - A database used to store the Merkle tree data.
* @param hasher - A hasher used to compute hash paths.
* @param name - Name of the tree.
* @returns The newly created tree.
*/
export async function loadTree(c, db, hasher, name) {
const meta = await db.get(name);
const { root, depth, size } = decodeMeta(meta);
const tree = new c(db, hasher, name, depth, size, root);
await tree.initFromDb();
return tree;
}
15 changes: 15 additions & 0 deletions build/module/lib/alternatives/log/console.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* Logger is a utility type that represents a logging function that accepts any number of arguments.
* It is used to provide customizable logging functionality, allowing developers to easily log messages
* with optional prefixes and custom formatting or output destinations.
*/
export type Logger = (...args: any[]) => void;
/**
* Creates a Logger function with an optional prefix for log messages.
* If a prefix is provided, the created logger will prepend it to each log message.
* If no prefix is provided, the default console.log will be returned.
*
* @param prefix - The optional string to prepend to each log message.
* @returns A Logger function that accepts any number of arguments and logs them with the specified prefix.
*/
export declare function createLogger(prefix: string): Logger;
38 changes: 38 additions & 0 deletions build/module/lib/alternatives/log/console.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* eslint-disable no-console */
/**
* ConsoleLogger is a utility class that provides customizable console logging functionality.
* It allows setting a custom prefix for log messages and an optional custom logger function,
* which can be useful for controlling the format of the output or redirecting logs to a different destination.
*/
class ConsoleLogger {
constructor(prefix, logger = console.log) {
this.prefix = prefix;
this.logger = logger;
}
/**
* Log messages with the specified prefix using the provided logger.
* By default, it uses 'console.log' as the logger but can be overridden
* during ConsoleLogger instantiation. This method allows for easy
* organization and readability of log messages in the console.
*
* @param args - The data to be logged, any number of arguments can be passed to this function.
*/
log(...args) {
this.logger(`${this.prefix}:`, ...args);
}
}
/**
* Creates a Logger function with an optional prefix for log messages.
* If a prefix is provided, the created logger will prepend it to each log message.
* If no prefix is provided, the default console.log will be returned.
*
* @param prefix - The optional string to prepend to each log message.
* @returns A Logger function that accepts any number of arguments and logs them with the specified prefix.
*/
export function createLogger(prefix) {
if (prefix) {
const logger = new ConsoleLogger(prefix, console.log);
return (...args) => logger.log(...args);
}
return console.log;
}
1 change: 1 addition & 0 deletions build/module/lib/alternatives/log/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './console.js';
1 change: 1 addition & 0 deletions build/module/lib/alternatives/log/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './console.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
63 changes: 63 additions & 0 deletions build/module/lib/alternatives/new_standard_index_tree_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { newTree } from './new_tree.js';
import { Level } from "level";
import { PoseidonHasher } from './types/index.js';
import { StandardIndexedTree } from './standard_indexed_tree/standard_indexed_tree.js';
import { Field, Provable } from 'o1js';
import { LeafData, verifyNonMembership } from "./standard_indexed_tree/verify_circuit.js";
// create a leveldb for test
let db = new Level('example-index-db', { valueEncoding: 'buffer' });
// poseidonHasher from o1js package
let poseidonHasher = new PoseidonHasher();
// tree height: 4
const PRIVATE_DATA_TREE_HEIGHT = 4;
// indicate if need consider the cached leaves, beside the existing leaves.
const includeUncommitted = true;
// create a standard merkle tree instance
const standardIndexedTreeInstance = await newTree(StandardIndexedTree, db, poseidonHasher, 'NULLIFIER_TREE', PRIVATE_DATA_TREE_HEIGHT);
console.log('standard indexed tree initial root: ', standardIndexedTreeInstance.getRoot(includeUncommitted).toString());
// append the first leaf of type: Field, the newly inserted leaf is kept in an array before being flushed into db.
await standardIndexedTreeInstance.appendLeaves([
Field('20468198949394563802460512965219839480612000520504690501918527632215047268421'),
]);
// before commit, you must get the leaf by specifying 'leafIndex' and 'includeUncommitted' = true
let leaf1 = await standardIndexedTreeInstance.getLeafValue(0n, includeUncommitted);
console.log('leaf1: ', leaf1?.toString());
// if you mistake specifying 'includeUncommitted' = false, then got 'undefined'. because the newly inserted leaf is not persisted yet.
leaf1 = await standardIndexedTreeInstance.getLeafValue(0n, !includeUncommitted);
console.log('leaf1: ', leaf1?.toString());
console.log('after append one leaf, tree root based on all cached&persisted leaves: ', standardIndexedTreeInstance.getRoot(includeUncommitted).toString());
let nowRootBeforeCommit = standardIndexedTreeInstance.getRoot(!includeUncommitted);
console.log('before commit, tree root based on existing persisted leaves: ', nowRootBeforeCommit.toString());
// persist, i.e. commit the tree into leveldb
await standardIndexedTreeInstance.commit();
console.log('exec commit... now all cached leaves are flushed into db and become parts of persisted leaves');
let nowRootAfterCommit = standardIndexedTreeInstance.getRoot(!includeUncommitted);
console.log('after commit, tree root based on all persisted leaves: ', nowRootAfterCommit.toString());
// after commit, now you could successfully get the leaf by specifying 'leafIndex' and 'includeUncommitted' = false
leaf1 = await standardIndexedTreeInstance.getLeafValue(0n, !includeUncommitted);
console.log('leaf1: ', leaf1);
// go on append several leaves
await standardIndexedTreeInstance.appendLeaves([Field(11)]);
await standardIndexedTreeInstance.appendLeaves([Field(21)]);
await standardIndexedTreeInstance.appendLeaves([Field(31)]);
await standardIndexedTreeInstance.appendLeaves([Field(41)]);
await standardIndexedTreeInstance.appendLeaves([Field(51)]);
await standardIndexedTreeInstance.appendLeaves([Field(61)]);
// commit the later newly inserted leaves into levelDB
await standardIndexedTreeInstance.commit();
// Non-Membership merkle witness
nowRootAfterCommit = standardIndexedTreeInstance.getRoot(!includeUncommitted);
const nullifier1 = Field(71n); // the nullifier to be inserted
const { index, alreadyPresent } = await standardIndexedTreeInstance.findIndexOfPreviousValue(nullifier1.toBigInt(), includeUncommitted);
if (alreadyPresent) { // if exist, then throw error.
throw new Error("nullifier1[${nullifier1}] existed!");
}
const predecessorSiblingPath = (await standardIndexedTreeInstance.getSiblingPath(BigInt(index), includeUncommitted));
const leafData = standardIndexedTreeInstance.getLatestLeafDataCopy(index, includeUncommitted);
const predecessorLeafData = new LeafData({ value: Field(leafData.value), nextIndex: Field(leafData.nextIndex), nextValue: Field(leafData.nextValue) });
const predecessorLeafDataIndex = Field(index);
// the membership witness of previous leaf is the Non-membership witness of 'nullifier1'
Provable.runAndCheck(() => {
verifyNonMembership(nowRootAfterCommit, nullifier1, predecessorLeafData, predecessorSiblingPath, predecessorLeafDataIndex);
Provable.log(`verify: true`);
});
1 change: 1 addition & 0 deletions build/module/lib/alternatives/new_standard_tree_test.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
Loading

0 comments on commit a8b4ca1

Please sign in to comment.