@aztec/world-state 0.0.0-test.0 → 0.0.1-commit.001888fc

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 (65) hide show
  1. package/dest/index.d.ts +1 -1
  2. package/dest/instrumentation/instrumentation.d.ts +6 -4
  3. package/dest/instrumentation/instrumentation.d.ts.map +1 -1
  4. package/dest/instrumentation/instrumentation.js +25 -41
  5. package/dest/native/bench_metrics.d.ts +23 -0
  6. package/dest/native/bench_metrics.d.ts.map +1 -0
  7. package/dest/native/bench_metrics.js +81 -0
  8. package/dest/native/fork_checkpoint.d.ts +7 -1
  9. package/dest/native/fork_checkpoint.d.ts.map +1 -1
  10. package/dest/native/fork_checkpoint.js +15 -3
  11. package/dest/native/index.d.ts +1 -1
  12. package/dest/native/merkle_trees_facade.d.ts +20 -8
  13. package/dest/native/merkle_trees_facade.d.ts.map +1 -1
  14. package/dest/native/merkle_trees_facade.js +80 -15
  15. package/dest/native/message.d.ts +83 -53
  16. package/dest/native/message.d.ts.map +1 -1
  17. package/dest/native/message.js +61 -61
  18. package/dest/native/native_world_state.d.ts +27 -19
  19. package/dest/native/native_world_state.d.ts.map +1 -1
  20. package/dest/native/native_world_state.js +103 -41
  21. package/dest/native/native_world_state_instance.d.ts +20 -4
  22. package/dest/native/native_world_state_instance.d.ts.map +1 -1
  23. package/dest/native/native_world_state_instance.js +43 -4
  24. package/dest/native/world_state_ops_queue.d.ts +1 -1
  25. package/dest/native/world_state_ops_queue.d.ts.map +1 -1
  26. package/dest/native/world_state_ops_queue.js +1 -1
  27. package/dest/synchronizer/config.d.ts +14 -6
  28. package/dest/synchronizer/config.d.ts.map +1 -1
  29. package/dest/synchronizer/config.js +33 -10
  30. package/dest/synchronizer/errors.d.ts +4 -0
  31. package/dest/synchronizer/errors.d.ts.map +1 -0
  32. package/dest/synchronizer/errors.js +5 -0
  33. package/dest/synchronizer/factory.d.ts +12 -4
  34. package/dest/synchronizer/factory.d.ts.map +1 -1
  35. package/dest/synchronizer/factory.js +13 -8
  36. package/dest/synchronizer/index.d.ts +1 -1
  37. package/dest/synchronizer/server_world_state_synchronizer.d.ts +21 -31
  38. package/dest/synchronizer/server_world_state_synchronizer.d.ts.map +1 -1
  39. package/dest/synchronizer/server_world_state_synchronizer.js +191 -96
  40. package/dest/test/index.d.ts +1 -1
  41. package/dest/test/utils.d.ts +12 -5
  42. package/dest/test/utils.d.ts.map +1 -1
  43. package/dest/test/utils.js +54 -47
  44. package/dest/testing.d.ts +3 -3
  45. package/dest/testing.d.ts.map +1 -1
  46. package/dest/testing.js +7 -11
  47. package/dest/world-state-db/index.d.ts +1 -1
  48. package/dest/world-state-db/merkle_tree_db.d.ts +12 -18
  49. package/dest/world-state-db/merkle_tree_db.d.ts.map +1 -1
  50. package/package.json +23 -24
  51. package/src/instrumentation/instrumentation.ts +31 -43
  52. package/src/native/bench_metrics.ts +91 -0
  53. package/src/native/fork_checkpoint.ts +19 -3
  54. package/src/native/merkle_trees_facade.ts +92 -20
  55. package/src/native/message.ts +105 -75
  56. package/src/native/native_world_state.ts +132 -52
  57. package/src/native/native_world_state_instance.ts +63 -10
  58. package/src/native/world_state_ops_queue.ts +1 -1
  59. package/src/synchronizer/config.ts +55 -21
  60. package/src/synchronizer/errors.ts +5 -0
  61. package/src/synchronizer/factory.ts +39 -10
  62. package/src/synchronizer/server_world_state_synchronizer.ts +227 -121
  63. package/src/test/utils.ts +92 -82
  64. package/src/testing.ts +4 -8
  65. package/src/world-state-db/merkle_tree_db.ts +16 -18
package/src/test/utils.ts CHANGED
@@ -4,107 +4,100 @@ import {
4
4
  NULLIFIER_SUBTREE_HEIGHT,
5
5
  NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
6
6
  } from '@aztec/constants';
7
+ import { asyncMap } from '@aztec/foundation/async-map';
8
+ import { BlockNumber, type CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types';
7
9
  import { padArrayEnd } from '@aztec/foundation/collection';
8
- import { Fr } from '@aztec/foundation/fields';
10
+ import { Fr } from '@aztec/foundation/curves/bn254';
9
11
  import { L2Block } from '@aztec/stdlib/block';
10
- import type { MerkleTreeReadOperations, MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
12
+ import type {
13
+ IndexedTreeId,
14
+ MerkleTreeReadOperations,
15
+ MerkleTreeWriteOperations,
16
+ } from '@aztec/stdlib/interfaces/server';
17
+ import { mockCheckpointAndMessages, mockL1ToL2Messages } from '@aztec/stdlib/testing';
11
18
  import { AppendOnlyTreeSnapshot, MerkleTreeId } from '@aztec/stdlib/trees';
19
+ import { BlockHeader } from '@aztec/stdlib/tx';
12
20
 
13
21
  import type { NativeWorldStateService } from '../native/native_world_state.js';
14
22
 
15
- export async function mockBlock(blockNum: number, size: number, fork: MerkleTreeWriteOperations) {
16
- const l2Block = await L2Block.random(blockNum, size);
17
- const l1ToL2Messages = Array(16).fill(0).map(Fr.random);
18
-
19
- // Sync the append only trees
20
- {
21
- const noteHashesPadded = l2Block.body.txEffects.flatMap(txEffect =>
22
- padArrayEnd(txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX),
23
- );
24
- await fork.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, noteHashesPadded);
25
-
26
- const l1ToL2MessagesPadded = padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
27
- await fork.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPadded);
28
- }
29
-
30
- // Sync the indexed trees
31
- {
32
- // We insert the public data tree leaves with one batch per tx to avoid updating the same key twice
33
- for (const txEffect of l2Block.body.txEffects) {
34
- await fork.batchInsert(
35
- MerkleTreeId.PUBLIC_DATA_TREE,
36
- txEffect.publicDataWrites.map(write => write.toBuffer()),
37
- 0,
38
- );
39
-
40
- const nullifiersPadded = padArrayEnd(txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX);
41
-
42
- await fork.batchInsert(
43
- MerkleTreeId.NULLIFIER_TREE,
44
- nullifiersPadded.map(nullifier => nullifier.toBuffer()),
45
- NULLIFIER_SUBTREE_HEIGHT,
46
- );
23
+ export async function updateBlockState(block: L2Block, l1ToL2Messages: Fr[], fork: MerkleTreeWriteOperations) {
24
+ const insertData = async (
25
+ treeId: IndexedTreeId,
26
+ data: Buffer[][],
27
+ subTreeHeight: number,
28
+ fork: MerkleTreeWriteOperations,
29
+ ) => {
30
+ for (const dataBatch of data) {
31
+ await fork.batchInsert(treeId, dataBatch, subTreeHeight);
47
32
  }
48
- }
33
+ };
34
+
35
+ const publicDataInsert = insertData(
36
+ MerkleTreeId.PUBLIC_DATA_TREE,
37
+ block.body.txEffects.map(txEffect => txEffect.publicDataWrites.map(write => write.toBuffer())),
38
+ 0,
39
+ fork,
40
+ );
41
+ const nullifierInsert = insertData(
42
+ MerkleTreeId.NULLIFIER_TREE,
43
+ block.body.txEffects.map(txEffect =>
44
+ padArrayEnd(txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX).map(nullifier => nullifier.toBuffer()),
45
+ ),
46
+ NULLIFIER_SUBTREE_HEIGHT,
47
+ fork,
48
+ );
49
+ const noteHashesPadded = block.body.txEffects.flatMap(txEffect =>
50
+ padArrayEnd(txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX),
51
+ );
52
+
53
+ const l1ToL2MessagesPadded =
54
+ block.indexWithinCheckpoint === 0
55
+ ? padArrayEnd<Fr, number>(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP)
56
+ : l1ToL2Messages;
57
+
58
+ const noteHashInsert = fork.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, noteHashesPadded);
59
+ const messageInsert = fork.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPadded);
60
+ await Promise.all([publicDataInsert, nullifierInsert, noteHashInsert, messageInsert]);
49
61
 
50
62
  const state = await fork.getStateReference();
51
- l2Block.header.state = state;
52
- await fork.updateArchive(l2Block.header);
63
+ block.header = BlockHeader.from({ ...block.header, state });
64
+ await fork.updateArchive(block.header);
53
65
 
54
66
  const archiveState = await fork.getTreeInfo(MerkleTreeId.ARCHIVE);
55
67
 
56
- l2Block.archive = new AppendOnlyTreeSnapshot(Fr.fromBuffer(archiveState.root), Number(archiveState.size));
68
+ block.archive = new AppendOnlyTreeSnapshot(Fr.fromBuffer(archiveState.root), Number(archiveState.size));
69
+ }
70
+
71
+ export async function mockBlock(
72
+ blockNum: BlockNumber,
73
+ size: number,
74
+ fork: MerkleTreeWriteOperations,
75
+ maxEffects: number | undefined = 1000, // Defaults to the maximum tx effects.
76
+ numL1ToL2Messages: number = NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
77
+ isFirstBlockInCheckpoint: boolean = true,
78
+ ) {
79
+ const block = await L2Block.random(blockNum, {
80
+ indexWithinCheckpoint: isFirstBlockInCheckpoint ? IndexWithinCheckpoint(0) : IndexWithinCheckpoint(1),
81
+ txsPerBlock: size,
82
+ txOptions: { maxEffects },
83
+ });
84
+ const l1ToL2Messages = mockL1ToL2Messages(numL1ToL2Messages);
85
+
86
+ await updateBlockState(block, l1ToL2Messages, fork);
57
87
 
58
88
  return {
59
- block: l2Block,
89
+ block,
60
90
  messages: l1ToL2Messages,
61
91
  };
62
92
  }
63
93
 
64
- export async function mockEmptyBlock(blockNum: number, fork: MerkleTreeWriteOperations) {
94
+ export async function mockEmptyBlock(blockNum: BlockNumber, fork: MerkleTreeWriteOperations) {
65
95
  const l2Block = L2Block.empty();
66
96
  const l1ToL2Messages = Array(16).fill(0).map(Fr.zero);
67
97
 
68
- l2Block.header.globalVariables.blockNumber = new Fr(blockNum);
98
+ l2Block.header.globalVariables.blockNumber = blockNum;
69
99
 
70
- // Sync the append only trees
71
- {
72
- const noteHashesPadded = l2Block.body.txEffects.flatMap(txEffect =>
73
- padArrayEnd(txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX),
74
- );
75
- await fork.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, noteHashesPadded);
76
-
77
- const l1ToL2MessagesPadded = padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
78
- await fork.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPadded);
79
- }
80
-
81
- // Sync the indexed trees
82
- {
83
- // We insert the public data tree leaves with one batch per tx to avoid updating the same key twice
84
- for (const txEffect of l2Block.body.txEffects) {
85
- await fork.batchInsert(
86
- MerkleTreeId.PUBLIC_DATA_TREE,
87
- txEffect.publicDataWrites.map(write => write.toBuffer()),
88
- 0,
89
- );
90
-
91
- const nullifiersPadded = padArrayEnd(txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX);
92
-
93
- await fork.batchInsert(
94
- MerkleTreeId.NULLIFIER_TREE,
95
- nullifiersPadded.map(nullifier => nullifier.toBuffer()),
96
- NULLIFIER_SUBTREE_HEIGHT,
97
- );
98
- }
99
- }
100
-
101
- const state = await fork.getStateReference();
102
- l2Block.header.state = state;
103
- await fork.updateArchive(l2Block.header);
104
-
105
- const archiveState = await fork.getTreeInfo(MerkleTreeId.ARCHIVE);
106
-
107
- l2Block.archive = new AppendOnlyTreeSnapshot(Fr.fromBuffer(archiveState.root), Number(archiveState.size));
100
+ await updateBlockState(l2Block, l1ToL2Messages, fork);
108
101
 
109
102
  return {
110
103
  block: l2Block,
@@ -112,13 +105,18 @@ export async function mockEmptyBlock(blockNum: number, fork: MerkleTreeWriteOper
112
105
  };
113
106
  }
114
107
 
115
- export async function mockBlocks(from: number, count: number, numTxs: number, worldState: NativeWorldStateService) {
116
- const tempFork = await worldState.fork(from - 1);
108
+ export async function mockBlocks(
109
+ from: BlockNumber,
110
+ count: number,
111
+ numTxs: number,
112
+ worldState: NativeWorldStateService,
113
+ ) {
114
+ const tempFork = await worldState.fork(BlockNumber(from - 1));
117
115
 
118
116
  const blocks = [];
119
117
  const messagesArray = [];
120
118
  for (let blockNumber = from; blockNumber < from + count; blockNumber++) {
121
- const { block, messages } = await mockBlock(blockNumber, numTxs, tempFork);
119
+ const { block, messages } = await mockBlock(BlockNumber(blockNumber), numTxs, tempFork);
122
120
  blocks.push(block);
123
121
  messagesArray.push(messages);
124
122
  }
@@ -128,6 +126,18 @@ export async function mockBlocks(from: number, count: number, numTxs: number, wo
128
126
  return { blocks, messages: messagesArray };
129
127
  }
130
128
 
129
+ export async function mockCheckpoint(
130
+ checkpointNumber: CheckpointNumber,
131
+ fork: MerkleTreeWriteOperations,
132
+ options: Partial<Parameters<typeof mockCheckpointAndMessages>[1]> = {},
133
+ ) {
134
+ const { checkpoint, messages } = await mockCheckpointAndMessages(checkpointNumber, options);
135
+ await asyncMap(checkpoint.blocks, async (block, i) => {
136
+ await updateBlockState(block, i === 0 ? messages : [], fork);
137
+ });
138
+ return { checkpoint, messages };
139
+ }
140
+
131
141
  export async function assertSameState(forkA: MerkleTreeReadOperations, forkB: MerkleTreeReadOperations) {
132
142
  const nativeStateRef = await forkA.getStateReference();
133
143
  const nativeArchive = await forkA.getTreeInfo(MerkleTreeId.ARCHIVE);
package/src/testing.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { GENESIS_ARCHIVE_ROOT, GENESIS_BLOCK_HASH } from '@aztec/constants';
2
- import { Fr } from '@aztec/foundation/fields';
1
+ import { GENESIS_ARCHIVE_ROOT } from '@aztec/constants';
2
+ import { Fr } from '@aztec/foundation/curves/bn254';
3
3
  import { computeFeePayerBalanceLeafSlot } from '@aztec/protocol-contracts/fee-juice';
4
4
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
5
5
  import { MerkleTreeId, PublicDataTreeLeaf } from '@aztec/stdlib/trees';
@@ -10,7 +10,6 @@ async function generateGenesisValues(prefilledPublicData: PublicDataTreeLeaf[])
10
10
  if (!prefilledPublicData.length) {
11
11
  return {
12
12
  genesisArchiveRoot: new Fr(GENESIS_ARCHIVE_ROOT),
13
- genesisBlockHash: new Fr(GENESIS_BLOCK_HASH),
14
13
  };
15
14
  }
16
15
 
@@ -20,14 +19,11 @@ async function generateGenesisValues(prefilledPublicData: PublicDataTreeLeaf[])
20
19
  true /* cleanupTmpDir */,
21
20
  prefilledPublicData,
22
21
  );
23
- const initialHeader = ws.getInitialHeader();
24
- const genesisBlockHash = await initialHeader.hash();
25
22
  const genesisArchiveRoot = new Fr((await ws.getCommitted().getTreeInfo(MerkleTreeId.ARCHIVE)).root);
26
23
  await ws.close();
27
24
 
28
25
  return {
29
26
  genesisArchiveRoot,
30
- genesisBlockHash,
31
27
  };
32
28
  }
33
29
 
@@ -50,11 +46,11 @@ export async function getGenesisValues(
50
46
 
51
47
  prefilledPublicData.sort((a, b) => (b.slot.lt(a.slot) ? 1 : -1));
52
48
 
53
- const { genesisBlockHash, genesisArchiveRoot } = await generateGenesisValues(prefilledPublicData);
49
+ const { genesisArchiveRoot } = await generateGenesisValues(prefilledPublicData);
54
50
 
55
51
  return {
56
52
  genesisArchiveRoot,
57
- genesisBlockHash,
58
53
  prefilledPublicData,
54
+ fundingNeeded: BigInt(initialAccounts.length) * initialAccountFeeJuice.toBigInt(),
59
55
  };
60
56
  }
@@ -1,9 +1,12 @@
1
1
  import { MAX_NULLIFIERS_PER_TX, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX } from '@aztec/constants';
2
- import type { Fr } from '@aztec/foundation/fields';
3
- import type { IndexedTreeSnapshot, TreeSnapshot } from '@aztec/merkle-tree';
2
+ import type { BlockNumber } from '@aztec/foundation/branded-types';
3
+ import type { Fr } from '@aztec/foundation/curves/bn254';
4
4
  import type { L2Block } from '@aztec/stdlib/block';
5
- import type { ForkMerkleTreeOperations, MerkleTreeReadOperations } from '@aztec/stdlib/interfaces/server';
6
- import type { MerkleTreeId } from '@aztec/stdlib/trees';
5
+ import type {
6
+ ForkMerkleTreeOperations,
7
+ MerkleTreeReadOperations,
8
+ ReadonlyWorldStateAccess,
9
+ } from '@aztec/stdlib/interfaces/server';
7
10
 
8
11
  import type { WorldStateStatusFull, WorldStateStatusSummary } from '../native/message.js';
9
12
 
@@ -26,15 +29,7 @@ export const INITIAL_NULLIFIER_TREE_SIZE = 2 * MAX_NULLIFIERS_PER_TX;
26
29
 
27
30
  export const INITIAL_PUBLIC_DATA_TREE_SIZE = 2 * MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX;
28
31
 
29
- export type TreeSnapshots = {
30
- [MerkleTreeId.NULLIFIER_TREE]: IndexedTreeSnapshot;
31
- [MerkleTreeId.NOTE_HASH_TREE]: TreeSnapshot<Fr>;
32
- [MerkleTreeId.PUBLIC_DATA_TREE]: IndexedTreeSnapshot;
33
- [MerkleTreeId.L1_TO_L2_MESSAGE_TREE]: TreeSnapshot<Fr>;
34
- [MerkleTreeId.ARCHIVE]: TreeSnapshot<Fr>;
35
- };
36
-
37
- export interface MerkleTreeAdminDatabase extends ForkMerkleTreeOperations {
32
+ export interface MerkleTreeAdminDatabase extends ForkMerkleTreeOperations, ReadonlyWorldStateAccess {
38
33
  /**
39
34
  * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree).
40
35
  * @param block - The L2 block to handle.
@@ -52,21 +47,21 @@ export interface MerkleTreeAdminDatabase extends ForkMerkleTreeOperations {
52
47
  * @param toBlockNumber The block number of the new oldest historical block
53
48
  * @returns The new WorldStateStatus
54
49
  */
55
- removeHistoricalBlocks(toBlockNumber: bigint): Promise<WorldStateStatusFull>;
50
+ removeHistoricalBlocks(toBlockNumber: BlockNumber): Promise<WorldStateStatusFull>;
56
51
 
57
52
  /**
58
53
  * Removes all pending blocks down to but not including the given block number
59
54
  * @param toBlockNumber The block number of the new tip of the pending chain,
60
55
  * @returns The new WorldStateStatus
61
56
  */
62
- unwindBlocks(toBlockNumber: bigint): Promise<WorldStateStatusFull>;
57
+ unwindBlocks(toBlockNumber: BlockNumber): Promise<WorldStateStatusFull>;
63
58
 
64
59
  /**
65
- * Advances the finalised block number to be the number provided
66
- * @param toBlockNumber The block number that is now the tip of the finalised chain
60
+ * Advances the finalized block number to be the number provided
61
+ * @param toBlockNumber The block number that is now the tip of the finalized chain
67
62
  * @returns The new WorldStateStatus
68
63
  */
69
- setFinalised(toBlockNumber: bigint): Promise<WorldStateStatusSummary>;
64
+ setFinalized(toBlockNumber: BlockNumber): Promise<WorldStateStatusSummary>;
70
65
 
71
66
  /**
72
67
  * Gets the current status summary of the database.
@@ -76,4 +71,7 @@ export interface MerkleTreeAdminDatabase extends ForkMerkleTreeOperations {
76
71
 
77
72
  /** Stops the database */
78
73
  close(): Promise<void>;
74
+
75
+ /** Deletes the db. */
76
+ clear(): Promise<void>;
79
77
  }