@aztec/world-state 0.1.0-alpha22 → 0.1.0-alpha39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/.tsbuildinfo +1 -1
  2. package/dest/index.d.ts +1 -0
  3. package/dest/index.d.ts.map +1 -1
  4. package/dest/index.js +2 -1
  5. package/dest/merkle-tree/merkle_tree_operations_facade.d.ts +7 -5
  6. package/dest/merkle-tree/merkle_tree_operations_facade.d.ts.map +1 -1
  7. package/dest/merkle-tree/merkle_tree_operations_facade.js +6 -5
  8. package/dest/synchroniser/config.d.ts +1 -1
  9. package/dest/synchroniser/config.d.ts.map +1 -1
  10. package/dest/synchroniser/config.js +3 -3
  11. package/dest/synchroniser/server_world_state_synchroniser.d.ts +3 -19
  12. package/dest/synchroniser/server_world_state_synchroniser.d.ts.map +1 -1
  13. package/dest/synchroniser/server_world_state_synchroniser.js +11 -23
  14. package/dest/synchroniser/server_world_state_synchroniser.test.js +11 -16
  15. package/dest/synchroniser/world_state_synchroniser.d.ts +24 -0
  16. package/dest/synchroniser/world_state_synchroniser.d.ts.map +1 -1
  17. package/dest/synchroniser/world_state_synchroniser.js +1 -1
  18. package/dest/utils.d.ts +6 -0
  19. package/dest/utils.d.ts.map +1 -1
  20. package/dest/utils.js +11 -2
  21. package/dest/world-state-db/index.d.ts +13 -7
  22. package/dest/world-state-db/index.d.ts.map +1 -1
  23. package/dest/world-state-db/index.js +2 -2
  24. package/dest/world-state-db/merkle_trees.d.ts +10 -6
  25. package/dest/world-state-db/merkle_trees.d.ts.map +1 -1
  26. package/dest/world-state-db/merkle_trees.js +44 -52
  27. package/package.json +6 -5
  28. package/src/index.ts +1 -0
  29. package/src/merkle-tree/merkle_tree_operations_facade.ts +10 -7
  30. package/src/synchroniser/config.ts +3 -3
  31. package/src/synchroniser/server_world_state_synchroniser.test.ts +21 -15
  32. package/src/synchroniser/server_world_state_synchroniser.ts +17 -23
  33. package/src/synchroniser/world_state_synchroniser.ts +30 -0
  34. package/src/utils.ts +13 -2
  35. package/src/world-state-db/index.ts +13 -8
  36. package/src/world-state-db/merkle_trees.ts +54 -77
@@ -1,32 +1,38 @@
1
1
  import {
2
2
  BaseRollupInputs,
3
3
  CONTRACT_TREE_HEIGHT,
4
- CONTRACT_TREE_ROOTS_TREE_HEIGHT,
5
4
  CircuitsWasm,
6
5
  Fr,
7
- L1_TO_L2_MSG_ROOTS_TREE_HEIGHT,
6
+ GlobalVariables,
7
+ HISTORIC_BLOCKS_TREE_HEIGHT,
8
8
  L1_TO_L2_MSG_TREE_HEIGHT,
9
9
  NULLIFIER_TREE_HEIGHT,
10
10
  PRIVATE_DATA_TREE_HEIGHT,
11
- PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT,
12
11
  PUBLIC_DATA_TREE_HEIGHT,
13
12
  } from '@aztec/circuits.js';
13
+ import { computeBlockHashWithGlobals } from '@aztec/circuits.js/abis';
14
+ import { SerialQueue } from '@aztec/foundation/fifo';
15
+ import { createDebugLogger } from '@aztec/foundation/log';
16
+ import { IWasmModule } from '@aztec/foundation/wasm';
14
17
  import {
15
18
  AppendOnlyTree,
16
19
  IndexedTree,
17
20
  LeafData,
18
21
  LowLeafWitnessData,
19
22
  Pedersen,
20
- SiblingPath,
21
23
  SparseTree,
22
24
  StandardIndexedTree,
23
25
  StandardTree,
24
26
  UpdateOnlyTree,
25
27
  newTree,
26
28
  } from '@aztec/merkle-tree';
29
+ import { L2Block, MerkleTreeId, SiblingPath, merkleTreeIds } from '@aztec/types';
30
+
27
31
  import { default as levelup } from 'levelup';
32
+
33
+ import { MerkleTreeOperationsFacade } from '../merkle-tree/merkle_tree_operations_facade.js';
28
34
  import {
29
- CurrentCommitmentTreeRoots,
35
+ CurrentTreeRoots,
30
36
  INITIAL_NULLIFIER_TREE_SIZE,
31
37
  IndexedTreeId,
32
38
  MerkleTreeDb,
@@ -34,11 +40,6 @@ import {
34
40
  PublicTreeId,
35
41
  TreeInfo,
36
42
  } from './index.js';
37
- import { MerkleTreeOperationsFacade } from '../merkle-tree/merkle_tree_operations_facade.js';
38
- import { L2Block, MerkleTreeId, merkleTreeIds } from '@aztec/types';
39
- import { SerialQueue } from '@aztec/foundation/fifo';
40
- import { createDebugLogger } from '@aztec/foundation/log';
41
- import { IWasmModule } from '@aztec/foundation/wasm';
42
43
 
43
44
  /**
44
45
  * A convenience class for managing multiple merkle trees.
@@ -63,13 +64,6 @@ export class MerkleTrees implements MerkleTreeDb {
63
64
  `${MerkleTreeId[MerkleTreeId.CONTRACT_TREE]}`,
64
65
  CONTRACT_TREE_HEIGHT,
65
66
  );
66
- const contractTreeRootsTree: AppendOnlyTree = await newTree(
67
- StandardTree,
68
- this.db,
69
- hasher,
70
- `${MerkleTreeId[MerkleTreeId.CONTRACT_TREE_ROOTS_TREE]}`,
71
- CONTRACT_TREE_ROOTS_TREE_HEIGHT,
72
- );
73
67
  const nullifierTree = await newTree(
74
68
  StandardIndexedTree,
75
69
  this.db,
@@ -85,13 +79,6 @@ export class MerkleTrees implements MerkleTreeDb {
85
79
  `${MerkleTreeId[MerkleTreeId.PRIVATE_DATA_TREE]}`,
86
80
  PRIVATE_DATA_TREE_HEIGHT,
87
81
  );
88
- const privateDataTreeRootsTree: AppendOnlyTree = await newTree(
89
- StandardTree,
90
- this.db,
91
- hasher,
92
- `${MerkleTreeId[MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE]}`,
93
- PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT,
94
- );
95
82
  const publicDataTree: UpdateOnlyTree = await newTree(
96
83
  SparseTree,
97
84
  this.db,
@@ -106,30 +93,20 @@ export class MerkleTrees implements MerkleTreeDb {
106
93
  `${MerkleTreeId[MerkleTreeId.L1_TO_L2_MESSAGES_TREE]}`,
107
94
  L1_TO_L2_MSG_TREE_HEIGHT,
108
95
  );
109
- const l1Tol2MessagesRootsTree: AppendOnlyTree = await newTree(
96
+ const historicBlocksTree: AppendOnlyTree = await newTree(
110
97
  StandardTree,
111
98
  this.db,
112
99
  hasher,
113
- `${MerkleTreeId[MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE]}`,
114
- L1_TO_L2_MSG_ROOTS_TREE_HEIGHT,
100
+ `${MerkleTreeId[MerkleTreeId.BLOCKS_TREE]}`,
101
+ HISTORIC_BLOCKS_TREE_HEIGHT,
115
102
  );
116
- this.trees = [
117
- contractTree,
118
- contractTreeRootsTree,
119
- nullifierTree,
120
- privateDataTree,
121
- privateDataTreeRootsTree,
122
- publicDataTree,
123
- l1Tol2MessagesTree,
124
- l1Tol2MessagesRootsTree,
125
- ];
103
+ this.trees = [contractTree, nullifierTree, privateDataTree, publicDataTree, l1Tol2MessagesTree, historicBlocksTree];
126
104
 
127
105
  this.jobQueue.start();
128
106
 
129
- // The roots trees must contain the empty roots of their data trees
130
- await this.updateHistoricRootsTrees(true);
131
- const historicRootsTrees = [contractTreeRootsTree, privateDataTreeRootsTree, l1Tol2MessagesRootsTree];
132
- await Promise.all(historicRootsTrees.map(tree => tree.commit()));
107
+ // The first leaf in the blocks tree contains the empty roots of the other trees and empty global variables.
108
+ await this.updateHistoricBlocksTree(GlobalVariables.empty(), true);
109
+ await historicBlocksTree.commit();
133
110
  }
134
111
 
135
112
  /**
@@ -170,17 +147,12 @@ export class MerkleTrees implements MerkleTreeDb {
170
147
  /**
171
148
  * Inserts into the roots trees (CONTRACT_TREE_ROOTS_TREE, PRIVATE_DATA_TREE_ROOTS_TREE, L1_TO_L2_MESSAGES_TREE_ROOTS_TREE)
172
149
  * the current roots of the corresponding trees (CONTRACT_TREE, PRIVATE_DATA_TREE, L1_TO_L2_MESSAGES_TREE).
150
+ * @param globals - The global variables to use for hashing.
173
151
  * @param includeUncommitted - Indicates whether to include uncommitted data.
174
152
  */
175
- public async updateHistoricRootsTrees(includeUncommitted: boolean) {
176
- for (const [newTree, rootTree] of [
177
- [MerkleTreeId.PRIVATE_DATA_TREE, MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE],
178
- [MerkleTreeId.CONTRACT_TREE, MerkleTreeId.CONTRACT_TREE_ROOTS_TREE],
179
- [MerkleTreeId.L1_TO_L2_MESSAGES_TREE, MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE],
180
- ] as const) {
181
- const newTreeInfo = await this.getTreeInfo(newTree, includeUncommitted);
182
- await this.appendLeaves(rootTree, [newTreeInfo.root]);
183
- }
153
+ public async updateHistoricBlocksTree(globals: GlobalVariables, includeUncommitted: boolean) {
154
+ const blockHash = await this.getCurrentBlockHash(globals, includeUncommitted);
155
+ await this.appendLeaves(MerkleTreeId.BLOCKS_TREE, [blockHash.toBuffer()]);
184
156
  }
185
157
 
186
158
  /**
@@ -198,22 +170,36 @@ export class MerkleTrees implements MerkleTreeDb {
198
170
  * @param includeUncommitted - Indicates whether to include uncommitted data.
199
171
  * @returns The current roots of the trees.
200
172
  */
201
- public getCommitmentTreeRoots(includeUncommitted: boolean): CurrentCommitmentTreeRoots {
202
- const roots = [
203
- MerkleTreeId.PRIVATE_DATA_TREE,
204
- MerkleTreeId.CONTRACT_TREE,
205
- MerkleTreeId.L1_TO_L2_MESSAGES_TREE,
206
- MerkleTreeId.NULLIFIER_TREE,
207
- ].map(tree => this.trees[tree].getRoot(includeUncommitted));
173
+ public getTreeRoots(includeUncommitted: boolean): CurrentTreeRoots {
174
+ const roots = this.getAllTreeRoots(includeUncommitted);
208
175
 
209
176
  return {
210
177
  privateDataTreeRoot: roots[0],
211
- contractDataTreeRoot: roots[1],
212
- l1Tol2MessagesTreeRoot: roots[2],
213
- nullifierTreeRoot: roots[3],
178
+ nullifierTreeRoot: roots[1],
179
+ contractDataTreeRoot: roots[2],
180
+ l1Tol2MessagesTreeRoot: roots[3],
181
+ publicDataTreeRoot: roots[4],
182
+ blocksTreeRoot: roots[5],
214
183
  };
215
184
  }
216
185
 
186
+ async getCurrentBlockHash(globals: GlobalVariables, includeUncommitted: boolean): Promise<Fr> {
187
+ const roots = this.getAllTreeRoots(includeUncommitted).map(root => Fr.fromBuffer(root));
188
+ const wasm = await CircuitsWasm.get();
189
+ return computeBlockHashWithGlobals(wasm, globals, roots[0], roots[1], roots[2], roots[3], roots[4]);
190
+ }
191
+
192
+ getAllTreeRoots(includeUncommitted: boolean): Buffer[] {
193
+ return [
194
+ MerkleTreeId.PRIVATE_DATA_TREE,
195
+ MerkleTreeId.NULLIFIER_TREE,
196
+ MerkleTreeId.CONTRACT_TREE,
197
+ MerkleTreeId.L1_TO_L2_MESSAGES_TREE,
198
+ MerkleTreeId.PUBLIC_DATA_TREE,
199
+ MerkleTreeId.BLOCKS_TREE,
200
+ ].map(tree => this.trees[tree].getRoot(includeUncommitted));
201
+ }
202
+
217
203
  /**
218
204
  * Gets the value at the given index.
219
205
  * @param treeId - The ID of the tree to get the leaf value from.
@@ -491,16 +477,8 @@ export class MerkleTrees implements MerkleTreeDb {
491
477
  compareRoot(l2Block.endNullifierTreeSnapshot.root, MerkleTreeId.NULLIFIER_TREE),
492
478
  compareRoot(l2Block.endPrivateDataTreeSnapshot.root, MerkleTreeId.PRIVATE_DATA_TREE),
493
479
  compareRoot(l2Block.endPublicDataTreeRoot, MerkleTreeId.PUBLIC_DATA_TREE),
494
- compareRoot(l2Block.endTreeOfHistoricContractTreeRootsSnapshot.root, MerkleTreeId.CONTRACT_TREE_ROOTS_TREE),
495
- compareRoot(
496
- l2Block.endTreeOfHistoricPrivateDataTreeRootsSnapshot.root,
497
- MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE,
498
- ),
499
480
  compareRoot(l2Block.endL1ToL2MessageTreeSnapshot.root, MerkleTreeId.L1_TO_L2_MESSAGES_TREE),
500
- compareRoot(
501
- l2Block.endTreeOfHistoricL1ToL2MessageTreeRootsSnapshot.root,
502
- MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE,
503
- ),
481
+ compareRoot(l2Block.endHistoricBlocksTreeSnapshot.root, MerkleTreeId.BLOCKS_TREE),
504
482
  ];
505
483
  const ourBlock = rootChecks.every(x => x);
506
484
  if (ourBlock) {
@@ -510,6 +488,7 @@ export class MerkleTrees implements MerkleTreeDb {
510
488
  this.log(`Block ${l2Block.number} is not ours, rolling back world state and committing state from chain..`);
511
489
  await this._rollback();
512
490
 
491
+ // Sync the append only trees
513
492
  for (const [tree, leaves] of [
514
493
  [MerkleTreeId.CONTRACT_TREE, l2Block.newContracts],
515
494
  [MerkleTreeId.PRIVATE_DATA_TREE, l2Block.newCommitments],
@@ -521,25 +500,23 @@ export class MerkleTrees implements MerkleTreeDb {
521
500
  );
522
501
  }
523
502
 
503
+ // Sync the indexed trees
524
504
  await (this.trees[MerkleTreeId.NULLIFIER_TREE] as StandardIndexedTree).batchInsert(
525
505
  l2Block.newNullifiers.map(fr => fr.toBuffer()),
526
506
  BaseRollupInputs.NULLIFIER_SUBTREE_HEIGHT,
527
507
  );
528
508
 
509
+ // Sync the public data tree
529
510
  for (const dataWrite of l2Block.newPublicDataWrites) {
530
511
  if (dataWrite.isEmpty()) continue;
531
512
  const { newValue, leafIndex } = dataWrite;
532
513
  await this._updateLeaf(MerkleTreeId.PUBLIC_DATA_TREE, newValue.toBuffer(), leafIndex.value);
533
514
  }
534
515
 
535
- for (const [newTree, rootTree] of [
536
- [MerkleTreeId.PRIVATE_DATA_TREE, MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE],
537
- [MerkleTreeId.CONTRACT_TREE, MerkleTreeId.CONTRACT_TREE_ROOTS_TREE],
538
- [MerkleTreeId.L1_TO_L2_MESSAGES_TREE, MerkleTreeId.L1_TO_L2_MESSAGES_ROOTS_TREE],
539
- ] as const) {
540
- const newTreeRoot = this.trees[newTree].getRoot(true);
541
- await this._appendLeaves(rootTree, [newTreeRoot]);
542
- }
516
+ // Sync and add the block to the historic blocks tree
517
+ const blockHash = await this.getCurrentBlockHash(l2Block.globalVariables, true);
518
+ await this._appendLeaves(MerkleTreeId.BLOCKS_TREE, [blockHash.toBuffer()]);
519
+
543
520
  await this._commit();
544
521
  }
545
522
  for (const treeId of merkleTreeIds()) {