From e3bdb65def87d757e229cbeaa45725092a6ad301 Mon Sep 17 00:00:00 2001 From: Charlie Lye Date: Sat, 16 Dec 2023 12:21:33 +0000 Subject: [PATCH] Unpick world state circulars. --- .../server_world_state_synchronizer.ts | 6 +- .../synchronizer/world_state_synchronizer.ts | 2 +- .../world-state/src/world-state-db/index.ts | 1 + .../src/world-state-db/merkle_tree_db.ts | 209 +----------------- .../world-state-db/merkle_tree_operations.ts | 203 +++++++++++++++++ .../merkle_tree_operations_facade.ts | 3 +- .../merkle_tree_snapshot_operations_facade.ts | 3 +- .../src/world-state-db/merkle_trees.ts | 8 +- 8 files changed, 218 insertions(+), 217 deletions(-) create mode 100644 yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts rename yarn-project/world-state/src/{merkle-tree => world-state-db}/merkle_tree_operations_facade.ts (97%) rename yarn-project/world-state/src/{merkle-tree => world-state-db}/merkle_tree_snapshot_operations_facade.ts (96%) diff --git a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts index 8c07bed87c4..200db8482a4 100644 --- a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts +++ b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts @@ -6,9 +6,9 @@ import { L2BlockHandledStats } from '@aztec/types/stats'; import { LevelUp } from 'levelup'; -import { HandleL2BlockResult, MerkleTreeOperations, MerkleTrees } from '../index.js'; -import { MerkleTreeOperationsFacade } from '../merkle-tree/merkle_tree_operations_facade.js'; -import { MerkleTreeSnapshotOperationsFacade } from '../merkle-tree/merkle_tree_snapshot_operations_facade.js'; +import { HandleL2BlockResult, MerkleTreeOperations, MerkleTrees } from '../world-state-db/index.js'; +import { MerkleTreeOperationsFacade } from '../world-state-db/merkle_tree_operations_facade.js'; +import { MerkleTreeSnapshotOperationsFacade } from '../world-state-db/merkle_tree_snapshot_operations_facade.js'; import { WorldStateConfig } from './config.js'; import { WorldStateRunningState, WorldStateStatus, WorldStateSynchronizer } from './world_state_synchronizer.js'; diff --git a/yarn-project/world-state/src/synchronizer/world_state_synchronizer.ts b/yarn-project/world-state/src/synchronizer/world_state_synchronizer.ts index 96e6885101a..51b8e1d4880 100644 --- a/yarn-project/world-state/src/synchronizer/world_state_synchronizer.ts +++ b/yarn-project/world-state/src/synchronizer/world_state_synchronizer.ts @@ -1,4 +1,4 @@ -import { MerkleTreeOperations } from '../index.js'; +import { MerkleTreeOperations } from '../world-state-db/index.js'; /** * Defines the possible states of the world state synchronizer. diff --git a/yarn-project/world-state/src/world-state-db/index.ts b/yarn-project/world-state/src/world-state-db/index.ts index 9ebc6f456d7..9d72e0991e8 100644 --- a/yarn-project/world-state/src/world-state-db/index.ts +++ b/yarn-project/world-state/src/world-state-db/index.ts @@ -1,2 +1,3 @@ export * from './merkle_trees.js'; export * from './merkle_tree_db.js'; +export * from './merkle_tree_operations.js'; diff --git a/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts b/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts index cc8a8493b7c..1828dc36362 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts @@ -1,18 +1,7 @@ -import { - MAX_NEW_NULLIFIERS_PER_TX, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - NullifierLeafPreimage, -} from '@aztec/circuits.js'; -import { Fr } from '@aztec/foundation/fields'; -import { createDebugLogger } from '@aztec/foundation/log'; -import { IndexedTreeLeafPreimage } from '@aztec/foundation/trees'; -import { BatchInsertionResult, IndexedTreeSnapshot, TreeSnapshot } from '@aztec/merkle-tree'; -import { L2Block, MerkleTreeId, SiblingPath } from '@aztec/types'; +import { MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX } from '@aztec/circuits.js'; +import { IndexedTreeSnapshot, TreeSnapshot } from '@aztec/merkle-tree'; -/** - * Type alias for the nullifier tree ID. - */ -export type IndexedTreeId = MerkleTreeId.NULLIFIER_TREE | MerkleTreeId.PUBLIC_DATA_TREE; +import { MerkleTreeOperations } from './merkle_tree_operations.js'; /** * @@ -33,29 +22,6 @@ export const INITIAL_NULLIFIER_TREE_SIZE = 2 * MAX_NEW_NULLIFIERS_PER_TX; export const INITIAL_PUBLIC_DATA_TREE_SIZE = 2 * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX; -/** - * Defines tree information. - */ -export interface TreeInfo { - /** - * The tree ID. - */ - treeId: MerkleTreeId; - /** - * The tree root. - */ - root: Buffer; - /** - * The number of leaves in the tree. - */ - size: bigint; - - /** - * The depth of the tree. - */ - depth: number; -} - /** * Adds a last boolean flag in each function on the type. */ @@ -63,24 +29,6 @@ type WithIncludeUncommitted = F extends (...args: [...infer Rest]) => infer R ? (...args: [...Rest, boolean]) => Return : F; -/** - * The current roots of the commitment trees - */ -export type CurrentTreeRoots = { - /** Note Hash Tree root. */ - noteHashTreeRoot: Buffer; - /** Contract data tree root. */ - contractDataTreeRoot: Buffer; - /** L1 to L2 Messages data tree root. */ - l1Tol2MessagesTreeRoot: Buffer; - /** Nullifier data tree root. */ - nullifierTreeRoot: Buffer; - /** Archive root. */ - archiveRoot: Buffer; - /** Public data tree root */ - publicDataTreeRoot: Buffer; -}; - /** * Defines the names of the setters on Merkle Trees. */ @@ -100,154 +48,3 @@ export type MerkleTreeDb = { */ getSnapshot(block: number): Promise>; }; - -/** - * Defines the interface for operations on a set of Merkle Trees. - */ -export interface MerkleTreeOperations { - /** - * Appends leaves to a given tree. - * @param treeId - The tree to be updated. - * @param leaves - The set of leaves to be appended. - */ - appendLeaves(treeId: MerkleTreeId, leaves: Buffer[]): Promise; - - /** - * Returns information about the given tree. - * @param treeId - The tree to be queried. - */ - getTreeInfo(treeId: MerkleTreeId): Promise; - - /** - * Gets the current roots of the commitment trees. - */ - getTreeRoots(): Promise; - - /** - * Gets sibling path for a leaf. - * @param treeId - The tree to be queried for a sibling path. - * @param index - The index of the leaf for which a sibling path should be returned. - */ - getSiblingPath(treeId: MerkleTreeId, index: bigint): Promise>; - - /** - * Returns the previous index for a given value in an indexed tree. - * @param treeId - The tree for which the previous value index is required. - * @param value - The value to be queried. - */ - getPreviousValueIndex( - treeId: IndexedTreeId, - value: bigint, - ): Promise< - | { - /** - * The index of the found leaf. - */ - index: bigint; - /** - * A flag indicating if the corresponding leaf's value is equal to `newValue`. - */ - alreadyPresent: boolean; - } - | undefined - >; - - /** - * Returns the data at a specific leaf. - * @param treeId - The tree for which leaf data should be returned. - * @param index - The index of the leaf required. - */ - getLeafPreimage(treeId: IndexedTreeId, index: bigint): Promise; - - /** - * Update the leaf data at the given index. - * @param treeId - The tree for which leaf data should be edited. - * @param leaf - The updated leaf value. - * @param index - The index of the leaf to be updated. - */ - updateLeaf(treeId: IndexedTreeId, leaf: NullifierLeafPreimage | Buffer, index: bigint): Promise; - - /** - * Returns the index containing a leaf value. - * @param treeId - The tree for which the index should be returned. - * @param value - The value to search for in the tree. - */ - findLeafIndex(treeId: MerkleTreeId, value: Buffer): Promise; - - /** - * Gets the value for a leaf in the tree. - * @param treeId - The tree for which the index should be returned. - * @param index - The index of the leaf. - */ - getLeafValue(treeId: MerkleTreeId, index: bigint): Promise; - - /** - * Inserts the new block hash into the archive. - * This includes all of the current roots of all of the data trees and the current blocks global vars. - * @param globalVariablesHash - The global variables hash to insert into the block hash. - */ - updateArchive(globalVariablesHash: Fr): Promise; - - /** - * Updates the latest global variables hash - * @param globalVariablesHash - The latest global variables hash - */ - updateLatestGlobalVariablesHash(globalVariablesHash: Fr): Promise; - - /** - * Gets the global variables hash from the previous block - */ - getLatestGlobalVariablesHash(): Promise; - - /** - * Batch insert multiple leaves into the tree. - * @param leaves - Leaves to insert into the tree. - * @param treeId - The tree on which to insert. - * @param subtreeHeight - Height of the subtree. - * @returns The witness data for the leaves to be updated when inserting the new ones. - */ - batchInsert( - treeId: MerkleTreeId, - leaves: Buffer[], - subtreeHeight: number, - ): Promise>; - - /** - * Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree). - * @param block - The L2 block to handle. - */ - handleL2Block(block: L2Block): Promise; - - /** - * Commits pending changes to the underlying store. - */ - commit(): Promise; - - /** - * Rolls back pending changes. - */ - rollback(): Promise; -} - -/** Return type for handleL2Block */ -export type HandleL2BlockResult = { - /** Whether the block processed was emitted by our sequencer */ isBlockOurs: boolean; -}; - -/** - * Outputs a tree leaves using for debugging purposes. - */ -export async function inspectTree( - db: MerkleTreeOperations, - treeId: MerkleTreeId, - log = createDebugLogger('aztec:inspect-tree'), -) { - const info = await db.getTreeInfo(treeId); - const output = [`Tree id=${treeId} size=${info.size} root=0x${info.root.toString('hex')}`]; - for (let i = 0; i < info.size; i++) { - output.push( - ` Leaf ${i}: ${await db.getLeafValue(treeId, BigInt(i)).then(x => x?.toString('hex') ?? '[undefined]')}`, - ); - } - log(output.join('\n')); -} diff --git a/yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts b/yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts new file mode 100644 index 00000000000..f016914c3ce --- /dev/null +++ b/yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts @@ -0,0 +1,203 @@ +import { NullifierLeafPreimage } from '@aztec/circuits.js'; +import { Fr } from '@aztec/foundation/fields'; +import { createDebugLogger } from '@aztec/foundation/log'; +import { IndexedTreeLeafPreimage } from '@aztec/foundation/trees'; +import { BatchInsertionResult } from '@aztec/merkle-tree'; +import { L2Block, MerkleTreeId, SiblingPath } from '@aztec/types'; + +/** + * Type alias for the nullifier tree ID. + */ +export type IndexedTreeId = MerkleTreeId.NULLIFIER_TREE | MerkleTreeId.PUBLIC_DATA_TREE; + +/** + * Defines tree information. + */ +export interface TreeInfo { + /** + * The tree ID. + */ + treeId: MerkleTreeId; + /** + * The tree root. + */ + root: Buffer; + /** + * The number of leaves in the tree. + */ + size: bigint; + + /** + * The depth of the tree. + */ + depth: number; +} + +/** + * The current roots of the commitment trees + */ +export type CurrentTreeRoots = { + /** Note Hash Tree root. */ + noteHashTreeRoot: Buffer; + /** Contract data tree root. */ + contractDataTreeRoot: Buffer; + /** L1 to L2 Messages data tree root. */ + l1Tol2MessagesTreeRoot: Buffer; + /** Nullifier data tree root. */ + nullifierTreeRoot: Buffer; + /** Archive root. */ + archiveRoot: Buffer; + /** Public data tree root */ + publicDataTreeRoot: Buffer; +}; + +/** + * Defines the interface for operations on a set of Merkle Trees. + */ +export interface MerkleTreeOperations { + /** + * Appends leaves to a given tree. + * @param treeId - The tree to be updated. + * @param leaves - The set of leaves to be appended. + */ + appendLeaves(treeId: MerkleTreeId, leaves: Buffer[]): Promise; + + /** + * Returns information about the given tree. + * @param treeId - The tree to be queried. + */ + getTreeInfo(treeId: MerkleTreeId): Promise; + + /** + * Gets the current roots of the commitment trees. + */ + getTreeRoots(): Promise; + + /** + * Gets sibling path for a leaf. + * @param treeId - The tree to be queried for a sibling path. + * @param index - The index of the leaf for which a sibling path should be returned. + */ + getSiblingPath(treeId: MerkleTreeId, index: bigint): Promise>; + + /** + * Returns the previous index for a given value in an indexed tree. + * @param treeId - The tree for which the previous value index is required. + * @param value - The value to be queried. + */ + getPreviousValueIndex( + treeId: IndexedTreeId, + value: bigint, + ): Promise< + | { + /** + * The index of the found leaf. + */ + index: bigint; + /** + * A flag indicating if the corresponding leaf's value is equal to `newValue`. + */ + alreadyPresent: boolean; + } + | undefined + >; + + /** + * Returns the data at a specific leaf. + * @param treeId - The tree for which leaf data should be returned. + * @param index - The index of the leaf required. + */ + getLeafPreimage(treeId: IndexedTreeId, index: bigint): Promise; + + /** + * Update the leaf data at the given index. + * @param treeId - The tree for which leaf data should be edited. + * @param leaf - The updated leaf value. + * @param index - The index of the leaf to be updated. + */ + updateLeaf(treeId: IndexedTreeId, leaf: NullifierLeafPreimage | Buffer, index: bigint): Promise; + + /** + * Returns the index containing a leaf value. + * @param treeId - The tree for which the index should be returned. + * @param value - The value to search for in the tree. + */ + findLeafIndex(treeId: MerkleTreeId, value: Buffer): Promise; + + /** + * Gets the value for a leaf in the tree. + * @param treeId - The tree for which the index should be returned. + * @param index - The index of the leaf. + */ + getLeafValue(treeId: MerkleTreeId, index: bigint): Promise; + + /** + * Inserts the new block hash into the archive. + * This includes all of the current roots of all of the data trees and the current blocks global vars. + * @param globalVariablesHash - The global variables hash to insert into the block hash. + */ + updateArchive(globalVariablesHash: Fr): Promise; + + /** + * Updates the latest global variables hash + * @param globalVariablesHash - The latest global variables hash + */ + updateLatestGlobalVariablesHash(globalVariablesHash: Fr): Promise; + + /** + * Gets the global variables hash from the previous block + */ + getLatestGlobalVariablesHash(): Promise; + + /** + * Batch insert multiple leaves into the tree. + * @param leaves - Leaves to insert into the tree. + * @param treeId - The tree on which to insert. + * @param subtreeHeight - Height of the subtree. + * @returns The witness data for the leaves to be updated when inserting the new ones. + */ + batchInsert( + treeId: MerkleTreeId, + leaves: Buffer[], + subtreeHeight: number, + ): Promise>; + + /** + * Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree). + * @param block - The L2 block to handle. + */ + handleL2Block(block: L2Block): Promise; + + /** + * Commits pending changes to the underlying store. + */ + commit(): Promise; + + /** + * Rolls back pending changes. + */ + rollback(): Promise; +} + +/** Return type for handleL2Block */ +export type HandleL2BlockResult = { + /** Whether the block processed was emitted by our sequencer */ isBlockOurs: boolean; +}; + +/** + * Outputs a tree leaves using for debugging purposes. + */ +export async function inspectTree( + db: MerkleTreeOperations, + treeId: MerkleTreeId, + log = createDebugLogger('aztec:inspect-tree'), +) { + const info = await db.getTreeInfo(treeId); + const output = [`Tree id=${treeId} size=${info.size} root=0x${info.root.toString('hex')}`]; + for (let i = 0; i < info.size; i++) { + output.push( + ` Leaf ${i}: ${await db.getLeafValue(treeId, BigInt(i)).then(x => x?.toString('hex') ?? '[undefined]')}`, + ); + } + log(output.join('\n')); +} diff --git a/yarn-project/world-state/src/merkle-tree/merkle_tree_operations_facade.ts b/yarn-project/world-state/src/world-state-db/merkle_tree_operations_facade.ts similarity index 97% rename from yarn-project/world-state/src/merkle-tree/merkle_tree_operations_facade.ts rename to yarn-project/world-state/src/world-state-db/merkle_tree_operations_facade.ts index 9f3f6976936..9f82810f855 100644 --- a/yarn-project/world-state/src/merkle-tree/merkle_tree_operations_facade.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_tree_operations_facade.ts @@ -4,7 +4,8 @@ import { IndexedTreeLeafPreimage } from '@aztec/foundation/trees'; import { BatchInsertionResult } from '@aztec/merkle-tree'; import { L2Block, MerkleTreeId, SiblingPath } from '@aztec/types'; -import { CurrentTreeRoots, HandleL2BlockResult, MerkleTreeDb, MerkleTreeOperations, TreeInfo } from '../index.js'; +import { MerkleTreeDb } from './merkle_tree_db.js'; +import { CurrentTreeRoots, HandleL2BlockResult, MerkleTreeOperations, TreeInfo } from './merkle_tree_operations.js'; /** * Wraps a MerkleTreeDbOperations to call all functions with a preset includeUncommitted flag. diff --git a/yarn-project/world-state/src/merkle-tree/merkle_tree_snapshot_operations_facade.ts b/yarn-project/world-state/src/world-state-db/merkle_tree_snapshot_operations_facade.ts similarity index 96% rename from yarn-project/world-state/src/merkle-tree/merkle_tree_snapshot_operations_facade.ts rename to yarn-project/world-state/src/world-state-db/merkle_tree_snapshot_operations_facade.ts index 54308855517..3f284d9ddb9 100644 --- a/yarn-project/world-state/src/merkle-tree/merkle_tree_snapshot_operations_facade.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_tree_snapshot_operations_facade.ts @@ -3,7 +3,8 @@ import { IndexedTreeLeafPreimage } from '@aztec/foundation/trees'; import { BatchInsertionResult, IndexedTreeSnapshot, TreeSnapshot } from '@aztec/merkle-tree'; import { MerkleTreeId, SiblingPath } from '@aztec/types'; -import { CurrentTreeRoots, HandleL2BlockResult, MerkleTreeDb, MerkleTreeOperations, TreeInfo } from '../index.js'; +import { MerkleTreeDb } from './merkle_tree_db.js'; +import { CurrentTreeRoots, HandleL2BlockResult, MerkleTreeOperations, TreeInfo } from './merkle_tree_operations.js'; /** * Merkle tree operations on readonly tree snapshots. diff --git a/yarn-project/world-state/src/world-state-db/merkle_trees.ts b/yarn-project/world-state/src/world-state-db/merkle_trees.ts index 2309d9de58b..31cc2446e34 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_trees.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_trees.ts @@ -35,17 +35,15 @@ import { Hasher, L2Block, MerkleTreeId, SiblingPath } from '@aztec/types'; import { default as levelup } from 'levelup'; -import { MerkleTreeOperationsFacade } from '../merkle-tree/merkle_tree_operations_facade.js'; +import { INITIAL_NULLIFIER_TREE_SIZE, INITIAL_PUBLIC_DATA_TREE_SIZE, MerkleTreeDb } from './merkle_tree_db.js'; import { CurrentTreeRoots, HandleL2BlockResult, - INITIAL_NULLIFIER_TREE_SIZE, - INITIAL_PUBLIC_DATA_TREE_SIZE, IndexedTreeId, - MerkleTreeDb, MerkleTreeOperations, TreeInfo, -} from './merkle_tree_db.js'; +} from './merkle_tree_operations.js'; +import { MerkleTreeOperationsFacade } from './merkle_tree_operations_facade.js'; /** * Data necessary to reinitialize the merkle trees from Db.