@aztec/prover-client 0.0.0-test.1 → 0.0.1-commit.1142ef1

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 (157) hide show
  1. package/dest/block-factory/index.d.ts +2 -0
  2. package/dest/block-factory/index.d.ts.map +1 -0
  3. package/dest/block-factory/light.d.ts +38 -0
  4. package/dest/block-factory/light.d.ts.map +1 -0
  5. package/dest/block-factory/light.js +106 -0
  6. package/dest/config.d.ts +8 -8
  7. package/dest/config.d.ts.map +1 -1
  8. package/dest/config.js +12 -2
  9. package/dest/index.d.ts +1 -1
  10. package/dest/light/index.d.ts +2 -0
  11. package/dest/light/index.d.ts.map +1 -0
  12. package/dest/light/index.js +1 -0
  13. package/dest/light/lightweight_checkpoint_builder.d.ts +43 -0
  14. package/dest/light/lightweight_checkpoint_builder.d.ts.map +1 -0
  15. package/dest/light/lightweight_checkpoint_builder.js +183 -0
  16. package/dest/mocks/fixtures.d.ts +8 -8
  17. package/dest/mocks/fixtures.d.ts.map +1 -1
  18. package/dest/mocks/fixtures.js +34 -16
  19. package/dest/mocks/test_context.d.ts +42 -32
  20. package/dest/mocks/test_context.d.ts.map +1 -1
  21. package/dest/mocks/test_context.js +144 -87
  22. package/dest/orchestrator/block-building-helpers.d.ts +37 -30
  23. package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
  24. package/dest/orchestrator/block-building-helpers.js +170 -189
  25. package/dest/orchestrator/block-proving-state.d.ts +70 -48
  26. package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
  27. package/dest/orchestrator/block-proving-state.js +282 -177
  28. package/dest/orchestrator/checkpoint-proving-state.d.ts +63 -0
  29. package/dest/orchestrator/checkpoint-proving-state.d.ts.map +1 -0
  30. package/dest/orchestrator/checkpoint-proving-state.js +210 -0
  31. package/dest/orchestrator/epoch-proving-state.d.ts +41 -27
  32. package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
  33. package/dest/orchestrator/epoch-proving-state.js +143 -73
  34. package/dest/orchestrator/index.d.ts +1 -1
  35. package/dest/orchestrator/orchestrator.d.ts +37 -34
  36. package/dest/orchestrator/orchestrator.d.ts.map +1 -1
  37. package/dest/orchestrator/orchestrator.js +788 -277
  38. package/dest/orchestrator/orchestrator_metrics.d.ts +1 -1
  39. package/dest/orchestrator/orchestrator_metrics.d.ts.map +1 -1
  40. package/dest/orchestrator/orchestrator_metrics.js +2 -6
  41. package/dest/orchestrator/tx-proving-state.d.ts +15 -12
  42. package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
  43. package/dest/orchestrator/tx-proving-state.js +27 -44
  44. package/dest/prover-client/factory.d.ts +3 -3
  45. package/dest/prover-client/factory.d.ts.map +1 -1
  46. package/dest/prover-client/index.d.ts +1 -1
  47. package/dest/prover-client/prover-client.d.ts +5 -5
  48. package/dest/prover-client/prover-client.d.ts.map +1 -1
  49. package/dest/prover-client/prover-client.js +6 -5
  50. package/dest/prover-client/server-epoch-prover.d.ts +16 -12
  51. package/dest/prover-client/server-epoch-prover.d.ts.map +1 -1
  52. package/dest/prover-client/server-epoch-prover.js +11 -11
  53. package/dest/proving_broker/broker_prover_facade.d.ts +25 -17
  54. package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
  55. package/dest/proving_broker/broker_prover_facade.js +59 -40
  56. package/dest/proving_broker/config.d.ts +19 -10
  57. package/dest/proving_broker/config.d.ts.map +1 -1
  58. package/dest/proving_broker/config.js +23 -6
  59. package/dest/proving_broker/factory.d.ts +2 -2
  60. package/dest/proving_broker/factory.d.ts.map +1 -1
  61. package/dest/proving_broker/factory.js +5 -1
  62. package/dest/proving_broker/fixtures.d.ts +3 -2
  63. package/dest/proving_broker/fixtures.d.ts.map +1 -1
  64. package/dest/proving_broker/fixtures.js +3 -2
  65. package/dest/proving_broker/index.d.ts +1 -1
  66. package/dest/proving_broker/proof_store/factory.d.ts +2 -2
  67. package/dest/proving_broker/proof_store/factory.js +1 -1
  68. package/dest/proving_broker/proof_store/gcs_proof_store.d.ts +1 -1
  69. package/dest/proving_broker/proof_store/gcs_proof_store.d.ts.map +1 -1
  70. package/dest/proving_broker/proof_store/gcs_proof_store.js +1 -0
  71. package/dest/proving_broker/proof_store/index.d.ts +2 -1
  72. package/dest/proving_broker/proof_store/index.d.ts.map +1 -1
  73. package/dest/proving_broker/proof_store/index.js +1 -0
  74. package/dest/proving_broker/proof_store/inline_proof_store.d.ts +1 -1
  75. package/dest/proving_broker/proof_store/inline_proof_store.d.ts.map +1 -1
  76. package/dest/proving_broker/proof_store/proof_store.d.ts +1 -1
  77. package/dest/proving_broker/proving_agent.d.ts +6 -11
  78. package/dest/proving_broker/proving_agent.d.ts.map +1 -1
  79. package/dest/proving_broker/proving_agent.js +84 -63
  80. package/dest/proving_broker/proving_broker.d.ts +13 -4
  81. package/dest/proving_broker/proving_broker.d.ts.map +1 -1
  82. package/dest/proving_broker/proving_broker.js +40 -33
  83. package/dest/proving_broker/proving_broker_database/memory.d.ts +3 -2
  84. package/dest/proving_broker/proving_broker_database/memory.d.ts.map +1 -1
  85. package/dest/proving_broker/proving_broker_database/memory.js +1 -1
  86. package/dest/proving_broker/proving_broker_database/persisted.d.ts +5 -3
  87. package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -1
  88. package/dest/proving_broker/proving_broker_database/persisted.js +401 -11
  89. package/dest/proving_broker/proving_broker_database.d.ts +3 -2
  90. package/dest/proving_broker/proving_broker_database.d.ts.map +1 -1
  91. package/dest/proving_broker/proving_broker_instrumentation.d.ts +1 -1
  92. package/dest/proving_broker/proving_broker_instrumentation.d.ts.map +1 -1
  93. package/dest/proving_broker/proving_broker_instrumentation.js +11 -35
  94. package/dest/proving_broker/proving_job_controller.d.ts +9 -9
  95. package/dest/proving_broker/proving_job_controller.d.ts.map +1 -1
  96. package/dest/proving_broker/proving_job_controller.js +87 -60
  97. package/dest/proving_broker/rpc.d.ts +4 -6
  98. package/dest/proving_broker/rpc.d.ts.map +1 -1
  99. package/dest/proving_broker/rpc.js +1 -4
  100. package/dest/test/mock_proof_store.d.ts +9 -0
  101. package/dest/test/mock_proof_store.d.ts.map +1 -0
  102. package/dest/test/mock_proof_store.js +10 -0
  103. package/dest/test/mock_prover.d.ts +23 -17
  104. package/dest/test/mock_prover.d.ts.map +1 -1
  105. package/dest/test/mock_prover.js +38 -20
  106. package/package.json +34 -31
  107. package/src/block-factory/index.ts +1 -0
  108. package/src/block-factory/light.ts +136 -0
  109. package/src/config.ts +25 -9
  110. package/src/light/index.ts +1 -0
  111. package/src/light/lightweight_checkpoint_builder.ts +249 -0
  112. package/src/mocks/fixtures.ts +44 -39
  113. package/src/mocks/test_context.ts +218 -116
  114. package/src/orchestrator/block-building-helpers.ts +258 -334
  115. package/src/orchestrator/block-proving-state.ts +325 -231
  116. package/src/orchestrator/checkpoint-proving-state.ts +303 -0
  117. package/src/orchestrator/epoch-proving-state.ts +191 -113
  118. package/src/orchestrator/orchestrator.ts +587 -318
  119. package/src/orchestrator/orchestrator_metrics.ts +2 -6
  120. package/src/orchestrator/tx-proving-state.ts +48 -66
  121. package/src/prover-client/factory.ts +6 -2
  122. package/src/prover-client/prover-client.ts +20 -25
  123. package/src/prover-client/server-epoch-prover.ts +40 -22
  124. package/src/proving_broker/broker_prover_facade.ts +206 -128
  125. package/src/proving_broker/config.ts +25 -7
  126. package/src/proving_broker/factory.ts +2 -1
  127. package/src/proving_broker/fixtures.ts +8 -3
  128. package/src/proving_broker/proof_store/factory.ts +1 -1
  129. package/src/proving_broker/proof_store/gcs_proof_store.ts +5 -1
  130. package/src/proving_broker/proof_store/index.ts +1 -0
  131. package/src/proving_broker/proof_store/inline_proof_store.ts +1 -1
  132. package/src/proving_broker/proving_agent.ts +90 -64
  133. package/src/proving_broker/proving_broker.ts +57 -41
  134. package/src/proving_broker/proving_broker_database/memory.ts +3 -2
  135. package/src/proving_broker/proving_broker_database/persisted.ts +29 -13
  136. package/src/proving_broker/proving_broker_database.ts +2 -1
  137. package/src/proving_broker/proving_broker_instrumentation.ts +10 -35
  138. package/src/proving_broker/proving_job_controller.ts +92 -81
  139. package/src/proving_broker/rpc.ts +1 -6
  140. package/src/test/mock_proof_store.ts +14 -0
  141. package/src/test/mock_prover.ts +156 -64
  142. package/dest/bin/get-proof-inputs.d.ts +0 -2
  143. package/dest/bin/get-proof-inputs.d.ts.map +0 -1
  144. package/dest/bin/get-proof-inputs.js +0 -51
  145. package/dest/block_builder/index.d.ts +0 -6
  146. package/dest/block_builder/index.d.ts.map +0 -1
  147. package/dest/block_builder/light.d.ts +0 -33
  148. package/dest/block_builder/light.d.ts.map +0 -1
  149. package/dest/block_builder/light.js +0 -82
  150. package/dest/proving_broker/proving_agent_instrumentation.d.ts +0 -8
  151. package/dest/proving_broker/proving_agent_instrumentation.d.ts.map +0 -1
  152. package/dest/proving_broker/proving_agent_instrumentation.js +0 -16
  153. package/src/bin/get-proof-inputs.ts +0 -59
  154. package/src/block_builder/index.ts +0 -6
  155. package/src/block_builder/light.ts +0 -101
  156. package/src/proving_broker/proving_agent_instrumentation.ts +0 -21
  157. /package/dest/{block_builder → block-factory}/index.js +0 -0
@@ -1,62 +1,64 @@
1
- import { Blob, type SpongeBlob } from '@aztec/blob-lib';
1
+ import {
2
+ BatchedBlobAccumulator,
3
+ SpongeBlob,
4
+ computeBlobsHashFromBlobs,
5
+ encodeBlockBlobData,
6
+ getBlobCommitmentsFromBlobs,
7
+ getBlobsPerL1Block,
8
+ } from '@aztec/blob-lib';
2
9
  import {
3
10
  ARCHIVE_HEIGHT,
11
+ CHONK_PROOF_LENGTH,
4
12
  MAX_CONTRACT_CLASS_LOGS_PER_TX,
5
13
  MAX_NOTE_HASHES_PER_TX,
6
14
  MAX_NULLIFIERS_PER_TX,
7
15
  NOTE_HASH_SUBTREE_HEIGHT,
8
- NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH,
16
+ NOTE_HASH_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
9
17
  NULLIFIER_SUBTREE_HEIGHT,
10
- NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH,
18
+ NULLIFIER_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
11
19
  NULLIFIER_TREE_HEIGHT,
12
- NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
13
20
  PUBLIC_DATA_TREE_HEIGHT,
14
21
  } from '@aztec/constants';
15
22
  import { makeTuple } from '@aztec/foundation/array';
23
+ import { BlockNumber } from '@aztec/foundation/branded-types';
16
24
  import { padArrayEnd } from '@aztec/foundation/collection';
17
- import { sha256Trunc } from '@aztec/foundation/crypto';
18
- import { Fr } from '@aztec/foundation/fields';
19
- import type { Logger } from '@aztec/foundation/log';
20
- import { type Tuple, assertLength, serializeToBuffer, toFriendlyJSON } from '@aztec/foundation/serialize';
21
- import { MembershipWitness, MerkleTreeCalculator, computeUnbalancedMerkleRoot } from '@aztec/foundation/trees';
22
- import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
23
- import { protocolContractTreeRoot } from '@aztec/protocol-contracts';
25
+ import { Fr } from '@aztec/foundation/curves/bn254';
26
+ import { type Bufferable, assertLength, toFriendlyJSON } from '@aztec/foundation/serialize';
27
+ import { MembershipWitness } from '@aztec/foundation/trees';
28
+ import { getVkData } from '@aztec/noir-protocol-circuits-types/server/vks';
29
+ import { getVKIndex, getVKSiblingPath } from '@aztec/noir-protocol-circuits-types/vk-tree';
24
30
  import { computeFeePayerBalanceLeafSlot } from '@aztec/protocol-contracts/fee-juice';
25
- import { PublicDataHint } from '@aztec/stdlib/avm';
26
31
  import { Body } from '@aztec/stdlib/block';
27
- import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
28
- import { ContractClassLog } from '@aztec/stdlib/logs';
29
- import type { ParityPublicInputs } from '@aztec/stdlib/parity';
32
+ import type { MerkleTreeWriteOperations, PublicInputsAndRecursiveProof } from '@aztec/stdlib/interfaces/server';
33
+ import { ContractClassLogFields } from '@aztec/stdlib/logs';
34
+ import { Proof, ProofData, RecursiveProof } from '@aztec/stdlib/proofs';
30
35
  import {
31
- type BaseOrMergeRollupPublicInputs,
32
- type BlockRootOrBlockMergePublicInputs,
33
- ConstantRollupData,
36
+ BlockConstantData,
37
+ BlockRollupPublicInputs,
34
38
  PrivateBaseRollupHints,
35
- PrivateBaseStateDiffHints,
36
39
  PublicBaseRollupHints,
40
+ PublicChonkVerifierPrivateInputs,
41
+ TreeSnapshotDiffHints,
37
42
  } from '@aztec/stdlib/rollup';
38
43
  import {
39
44
  AppendOnlyTreeSnapshot,
40
45
  MerkleTreeId,
41
46
  NullifierLeafPreimage,
42
- PublicDataTreeLeaf,
43
47
  PublicDataTreeLeafPreimage,
44
48
  getTreeHeight,
45
49
  } from '@aztec/stdlib/trees';
46
50
  import {
47
51
  BlockHeader,
48
- ContentCommitment,
49
- type GlobalVariables,
52
+ GlobalVariables,
50
53
  PartialStateReference,
51
54
  type ProcessedTx,
52
55
  StateReference,
53
- TxEffect,
56
+ Tx,
54
57
  } from '@aztec/stdlib/tx';
58
+ import { VkData } from '@aztec/stdlib/vks';
55
59
  import { Attributes, type Span, runInSpan } from '@aztec/telemetry-client';
56
60
  import type { MerkleTreeReadOperations } from '@aztec/world-state';
57
61
 
58
- import { inspect } from 'util';
59
-
60
62
  /**
61
63
  * Type representing the names of the trees for the base rollup.
62
64
  */
@@ -67,242 +69,236 @@ type BaseTreeNames = 'NoteHashTree' | 'ContractTree' | 'NullifierTree' | 'Public
67
69
  export type TreeNames = BaseTreeNames | 'L1ToL2MessageTree' | 'Archive';
68
70
 
69
71
  // Builds the hints for base rollup. Updating the contract, nullifier, and data trees in the process.
70
- export const buildBaseRollupHints = runInSpan(
72
+ export const insertSideEffectsAndBuildBaseRollupHints = runInSpan(
71
73
  'BlockBuilderHelpers',
72
74
  'buildBaseRollupHints',
73
75
  async (
74
76
  span: Span,
75
77
  tx: ProcessedTx,
76
- globalVariables: GlobalVariables,
77
- db: MerkleTreeWriteOperations,
78
+ lastArchive: AppendOnlyTreeSnapshot,
79
+ newL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot,
78
80
  startSpongeBlob: SpongeBlob,
81
+ proverId: Fr,
82
+ db: MerkleTreeWriteOperations,
79
83
  ) => {
80
84
  span.setAttribute(Attributes.TX_HASH, tx.hash.toString());
81
85
  // Get trees info before any changes hit
82
- const constants = await getConstantRollupData(globalVariables, db);
83
86
  const start = new PartialStateReference(
84
87
  await getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE, db),
85
88
  await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE, db),
86
89
  await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE, db),
87
90
  );
88
- // Get the subtree sibling paths for the circuit
89
- const noteHashSubtreeSiblingPathArray = await getSubtreeSiblingPath(
90
- MerkleTreeId.NOTE_HASH_TREE,
91
- NOTE_HASH_SUBTREE_HEIGHT,
92
- db,
93
- );
94
91
 
95
- const noteHashSubtreeSiblingPath = makeTuple(NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, i =>
96
- i < noteHashSubtreeSiblingPathArray.length ? noteHashSubtreeSiblingPathArray[i] : Fr.ZERO,
92
+ // Get the note hash subtree root sibling path for insertion.
93
+ const noteHashSubtreeRootSiblingPath = assertLength(
94
+ await getSubtreeSiblingPath(MerkleTreeId.NOTE_HASH_TREE, NOTE_HASH_SUBTREE_HEIGHT, db),
95
+ NOTE_HASH_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
97
96
  );
98
97
 
99
- // Update the note hash trees with the new items being inserted to get the new roots
100
- // that will be used by the next iteration of the base rollup circuit, skipping the empty ones
101
- const noteHashes = padArrayEnd(tx.txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX);
102
- await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, noteHashes);
103
-
104
- // Create data hint for reading fee payer initial balance in Fee Juice
105
- const leafSlot = await computeFeePayerBalanceLeafSlot(tx.data.feePayer);
106
- const feePayerFeeJuiceBalanceReadHint = await getPublicDataHint(db, leafSlot.toBigInt());
107
-
108
- // The read witnesses for a given TX should be generated before the writes of the same TX are applied.
109
- // All reads that refer to writes in the same tx are transient and can be simplified out.
110
- const txPublicDataUpdateRequestInfo = await processPublicDataUpdateRequests(tx, db);
111
-
112
- // Update the nullifier tree, capturing the low nullifier info for each individual operation
113
- const {
114
- lowLeavesWitnessData: nullifierWitnessLeaves,
115
- newSubtreeSiblingPath: nullifiersSubtreeSiblingPath,
116
- sortedNewLeaves: sortednullifiers,
117
- sortedNewLeavesIndexes,
118
- } = await db.batchInsert(
119
- MerkleTreeId.NULLIFIER_TREE,
120
- padArrayEnd(tx.txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX).map(n => n.toBuffer()),
121
- NULLIFIER_SUBTREE_HEIGHT,
122
- );
123
-
124
- if (nullifierWitnessLeaves === undefined) {
125
- throw new Error(`Could not craft nullifier batch insertion proofs`);
126
- }
127
-
128
- // Extract witness objects from returned data
129
- const nullifierPredecessorMembershipWitnessesWithoutPadding: MembershipWitness<typeof NULLIFIER_TREE_HEIGHT>[] =
130
- nullifierWitnessLeaves.map(l =>
131
- MembershipWitness.fromBufferArray(l.index, assertLength(l.siblingPath.toBufferArray(), NULLIFIER_TREE_HEIGHT)),
132
- );
133
-
134
- const nullifierSubtreeSiblingPathArray = nullifiersSubtreeSiblingPath.toFields();
135
-
136
- const nullifierSubtreeSiblingPath = makeTuple(NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, i =>
137
- i < nullifierSubtreeSiblingPathArray.length ? nullifierSubtreeSiblingPathArray[i] : Fr.ZERO,
138
- );
98
+ const { nullifierInsertionResult, publicDataInsertionResult } = await insertSideEffects(tx, db);
139
99
 
140
- // Append new data to startSpongeBlob
141
- const inputSpongeBlob = startSpongeBlob.clone();
142
- await startSpongeBlob.absorb(tx.txEffect.toBlobFields());
100
+ const blockHash = await tx.data.constants.anchorBlockHeader.hash();
101
+ const anchorBlockArchiveSiblingPath = (
102
+ await getMembershipWitnessFor(blockHash, MerkleTreeId.ARCHIVE, ARCHIVE_HEIGHT, db)
103
+ ).siblingPath;
143
104
 
144
- const contractClassLogsPreimages = makeTuple(
105
+ const contractClassLogsFields = makeTuple(
145
106
  MAX_CONTRACT_CLASS_LOGS_PER_TX,
146
- i => tx.txEffect.contractClassLogs[i]?.toUnsiloed() || ContractClassLog.empty(),
107
+ i => tx.txEffect.contractClassLogs[i]?.fields || ContractClassLogFields.empty(),
147
108
  );
148
109
 
149
110
  if (tx.avmProvingRequest) {
150
- const blockHash = await tx.constants.historicalHeader.hash();
151
- const archiveRootMembershipWitness = await getMembershipWitnessFor(
152
- blockHash,
153
- MerkleTreeId.ARCHIVE,
154
- ARCHIVE_HEIGHT,
155
- db,
156
- );
157
-
158
111
  return PublicBaseRollupHints.from({
159
- startSpongeBlob: inputSpongeBlob,
160
- archiveRootMembershipWitness,
161
- contractClassLogsPreimages,
162
- constants,
112
+ startSpongeBlob,
113
+ lastArchive,
114
+ anchorBlockArchiveSiblingPath,
115
+ contractClassLogsFields,
163
116
  });
164
117
  } else {
165
- if (
166
- txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses.length > 1 ||
167
- txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages.length > 1 ||
168
- txPublicDataUpdateRequestInfo.publicDataWritesSiblingPaths.length > 1
169
- ) {
118
+ if (tx.txEffect.publicDataWrites.length > 1) {
170
119
  throw new Error(`More than one public data write in a private only tx`);
171
120
  }
172
121
 
173
- const feeWriteLowLeafPreimage =
174
- txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages[0] || PublicDataTreeLeafPreimage.empty();
175
- const feeWriteLowLeafMembershipWitness =
176
- txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses[0] ||
177
- MembershipWitness.empty<typeof PUBLIC_DATA_TREE_HEIGHT>(PUBLIC_DATA_TREE_HEIGHT);
178
- const feeWriteSiblingPath =
179
- txPublicDataUpdateRequestInfo.publicDataWritesSiblingPaths[0] ||
180
- makeTuple(PUBLIC_DATA_TREE_HEIGHT, () => Fr.ZERO);
181
-
182
- const stateDiffHints = PrivateBaseStateDiffHints.from({
183
- nullifierPredecessorPreimages: makeTuple(MAX_NULLIFIERS_PER_TX, i =>
184
- i < nullifierWitnessLeaves.length
185
- ? (nullifierWitnessLeaves[i].leafPreimage as NullifierLeafPreimage)
186
- : NullifierLeafPreimage.empty(),
187
- ),
188
- nullifierPredecessorMembershipWitnesses: makeTuple(MAX_NULLIFIERS_PER_TX, i =>
189
- i < nullifierPredecessorMembershipWitnessesWithoutPadding.length
190
- ? nullifierPredecessorMembershipWitnessesWithoutPadding[i]
191
- : makeEmptyMembershipWitness(NULLIFIER_TREE_HEIGHT),
122
+ // Get hints for reading fee payer's balance in the public data tree.
123
+ const feePayerBalanceLeafWitnessData = publicDataInsertionResult.lowLeavesWitnessData[0];
124
+ const feePayerBalanceMembershipWitness = MembershipWitness.fromBufferArray<typeof PUBLIC_DATA_TREE_HEIGHT>(
125
+ feePayerBalanceLeafWitnessData.index,
126
+ assertLength(feePayerBalanceLeafWitnessData.siblingPath.toBufferArray(), PUBLIC_DATA_TREE_HEIGHT),
127
+ );
128
+ const feePayerBalanceLeafPreimage = feePayerBalanceLeafWitnessData.leafPreimage as PublicDataTreeLeafPreimage;
129
+ const leafSlot = await computeFeePayerBalanceLeafSlot(tx.data.feePayer);
130
+ if (!leafSlot.equals(feePayerBalanceLeafPreimage.leaf.slot)) {
131
+ throw new Error(`Cannot find the public data tree leaf for the fee payer's balance`);
132
+ }
133
+
134
+ // Get hints for inserting the nullifiers.
135
+ const nullifierLowLeavesWitnessData = nullifierInsertionResult.lowLeavesWitnessData!;
136
+ const nullifierPredecessorPreimages = padArrayEnd(
137
+ nullifierLowLeavesWitnessData.map(l => l.leafPreimage as NullifierLeafPreimage),
138
+ NullifierLeafPreimage.empty(),
139
+ MAX_NULLIFIERS_PER_TX,
140
+ );
141
+ const nullifierPredecessorMembershipWitnesses = padArrayEnd(
142
+ nullifierLowLeavesWitnessData.map(l =>
143
+ MembershipWitness.fromBufferArray<typeof NULLIFIER_TREE_HEIGHT>(
144
+ l.index,
145
+ assertLength(l.siblingPath.toBufferArray(), NULLIFIER_TREE_HEIGHT),
146
+ ),
192
147
  ),
193
- sortedNullifiers: makeTuple(MAX_NULLIFIERS_PER_TX, i => Fr.fromBuffer(sortednullifiers[i])),
194
- sortedNullifierIndexes: makeTuple(MAX_NULLIFIERS_PER_TX, i => sortedNewLeavesIndexes[i]),
195
- noteHashSubtreeSiblingPath,
196
- nullifierSubtreeSiblingPath,
197
- feeWriteLowLeafPreimage,
198
- feeWriteLowLeafMembershipWitness,
199
- feeWriteSiblingPath,
148
+ makeEmptyMembershipWitness(NULLIFIER_TREE_HEIGHT),
149
+ MAX_NULLIFIERS_PER_TX,
150
+ );
151
+ const sortedNullifiers = assertLength(
152
+ nullifierInsertionResult.sortedNewLeaves.map(n => Fr.fromBuffer(n)),
153
+ MAX_NULLIFIERS_PER_TX,
154
+ );
155
+ const sortedNullifierIndexes = assertLength(
156
+ nullifierInsertionResult.sortedNewLeavesIndexes,
157
+ MAX_NULLIFIERS_PER_TX,
158
+ );
159
+ const nullifierSubtreeRootSiblingPath = assertLength(
160
+ nullifierInsertionResult.newSubtreeSiblingPath.toFields(),
161
+ NULLIFIER_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
162
+ );
163
+
164
+ const treeSnapshotDiffHints = TreeSnapshotDiffHints.from({
165
+ noteHashSubtreeRootSiblingPath,
166
+ nullifierPredecessorPreimages,
167
+ nullifierPredecessorMembershipWitnesses,
168
+ sortedNullifiers,
169
+ sortedNullifierIndexes,
170
+ nullifierSubtreeRootSiblingPath,
171
+ feePayerBalanceMembershipWitness,
200
172
  });
201
173
 
202
- const blockHash = await tx.constants.historicalHeader.hash();
203
- const archiveRootMembershipWitness = await getMembershipWitnessFor(
204
- blockHash,
205
- MerkleTreeId.ARCHIVE,
206
- ARCHIVE_HEIGHT,
207
- db,
208
- );
174
+ const constants = BlockConstantData.from({
175
+ lastArchive,
176
+ l1ToL2TreeSnapshot: newL1ToL2MessageTreeSnapshot,
177
+ vkTreeRoot: tx.data.constants.vkTreeRoot,
178
+ protocolContractsHash: tx.data.constants.protocolContractsHash,
179
+ globalVariables: tx.globalVariables,
180
+ proverId,
181
+ });
209
182
 
210
183
  return PrivateBaseRollupHints.from({
211
184
  start,
212
- startSpongeBlob: inputSpongeBlob,
213
- stateDiffHints,
214
- feePayerFeeJuiceBalanceReadHint,
215
- archiveRootMembershipWitness,
216
- contractClassLogsPreimages,
185
+ startSpongeBlob,
186
+ treeSnapshotDiffHints,
187
+ feePayerBalanceLeafPreimage,
188
+ anchorBlockArchiveSiblingPath,
189
+ contractClassLogsFields,
217
190
  constants,
218
191
  });
219
192
  }
220
193
  },
221
194
  );
222
195
 
223
- export async function getPublicDataHint(db: MerkleTreeWriteOperations, leafSlot: bigint) {
224
- const { index } = (await db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot)) ?? {};
225
- if (index === undefined) {
226
- throw new Error(`Cannot find the previous value index for public data ${leafSlot}.`);
227
- }
196
+ export const insertSideEffects = runInSpan(
197
+ 'BlockBuilderHelpers',
198
+ 'buildBaseRollupHints',
199
+ async (span: Span, tx: ProcessedTx, db: MerkleTreeWriteOperations) => {
200
+ span.setAttribute(Attributes.TX_HASH, tx.hash.toString());
228
201
 
229
- const siblingPath = await db.getSiblingPath<typeof PUBLIC_DATA_TREE_HEIGHT>(MerkleTreeId.PUBLIC_DATA_TREE, index);
230
- const membershipWitness = new MembershipWitness(PUBLIC_DATA_TREE_HEIGHT, index, siblingPath.toTuple());
202
+ // Insert the note hashes. Padded with zeros to the max number of note hashes per tx.
203
+ const noteHashes = padArrayEnd(tx.txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX);
204
+ await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, noteHashes);
231
205
 
232
- const leafPreimage = (await db.getLeafPreimage(MerkleTreeId.PUBLIC_DATA_TREE, index)) as PublicDataTreeLeafPreimage;
233
- if (!leafPreimage) {
234
- throw new Error(`Cannot find the leaf preimage for public data tree at index ${index}.`);
235
- }
206
+ // Insert the nullifiers. Padded with zeros to the max number of nullifiers per tx.
207
+ // Capturing the low nullifier info for each individual operation.
208
+ const nullifierInsertionResult = await db.batchInsert(
209
+ MerkleTreeId.NULLIFIER_TREE,
210
+ padArrayEnd(tx.txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX).map(n => n.toBuffer()),
211
+ NULLIFIER_SUBTREE_HEIGHT,
212
+ );
213
+ if (nullifierInsertionResult.lowLeavesWitnessData === undefined) {
214
+ throw new Error(`Failed to batch insert nullifiers.`);
215
+ }
216
+
217
+ if (tx.txEffect.publicDataWrites.some(write => write.isEmpty())) {
218
+ throw new Error(`Empty public data write in tx: ${toFriendlyJSON(tx)}.`);
219
+ }
220
+ // Insert the public data writes sequentially. No need to pad them to the max array size.
221
+ // Capturing the low leaf info for each individual operation.
222
+ const publicDataInsertionResult = await db.sequentialInsert(
223
+ MerkleTreeId.PUBLIC_DATA_TREE,
224
+ tx.txEffect.publicDataWrites.map(write => write.toBuffer()),
225
+ );
236
226
 
237
- const exists = leafPreimage.slot.toBigInt() === leafSlot;
238
- const value = exists ? leafPreimage.value : Fr.ZERO;
227
+ return {
228
+ nullifierInsertionResult,
229
+ publicDataInsertionResult,
230
+ };
231
+ },
232
+ );
233
+
234
+ export function getChonkProofFromTx(tx: Tx | ProcessedTx) {
235
+ const publicInputs = tx.data.publicInputs().toFields();
236
+
237
+ const binaryProof = new Proof(
238
+ Buffer.concat(tx.chonkProof.attachPublicInputs(publicInputs).fieldsWithPublicInputs.map(field => field.toBuffer())),
239
+ publicInputs.length,
240
+ );
241
+ return new RecursiveProof(tx.chonkProof.fields, binaryProof, true, CHONK_PROOF_LENGTH);
242
+ }
239
243
 
240
- return new PublicDataHint(new Fr(leafSlot), value, membershipWitness, leafPreimage);
244
+ export function getPublicChonkVerifierPrivateInputsFromTx(tx: Tx | ProcessedTx, proverId: Fr) {
245
+ const proofData = new ProofData(
246
+ tx.data.toPrivateToPublicKernelCircuitPublicInputs(),
247
+ getChonkProofFromTx(tx),
248
+ getVkData('HidingKernelToPublic'),
249
+ );
250
+ return new PublicChonkVerifierPrivateInputs(proofData, proverId);
241
251
  }
242
252
 
243
- export const buildBlobHints = runInSpan(
253
+ // Build "hints" as the private inputs for the checkpoint root rollup circuit.
254
+ // The `blobCommitments` will be accumulated and checked in the root rollup against the `finalBlobChallenges`.
255
+ // The `blobsHash` will be validated on L1 against the submitted blob data.
256
+ export const buildBlobHints = (blobFields: Fr[]) => {
257
+ const blobs = getBlobsPerL1Block(blobFields);
258
+ const blobCommitments = getBlobCommitmentsFromBlobs(blobs);
259
+ const blobsHash = computeBlobsHashFromBlobs(blobs);
260
+ return { blobCommitments, blobs, blobsHash };
261
+ };
262
+
263
+ export const buildFinalBlobChallenges = async (blobFieldsPerCheckpoint: Fr[][]) => {
264
+ return await BatchedBlobAccumulator.precomputeBatchedBlobChallenges(blobFieldsPerCheckpoint);
265
+ };
266
+
267
+ export const accumulateBlobs = runInSpan(
244
268
  'BlockBuilderHelpers',
245
- 'buildBlobHints',
246
- async (_span: Span, txEffects: TxEffect[]) => {
247
- const blobFields = txEffects.flatMap(tx => tx.toBlobFields());
248
- const blobs = await Blob.getBlobs(blobFields);
249
- const blobCommitments = blobs.map(b => b.commitmentToFields());
250
- const blobsHash = new Fr(getBlobsHashFromBlobs(blobs));
251
- return { blobFields, blobCommitments, blobs, blobsHash };
269
+ 'accumulateBlobs',
270
+ async (_span: Span, blobFields: Fr[], startBlobAccumulator: BatchedBlobAccumulator) => {
271
+ const endBlobAccumulator = await startBlobAccumulator.accumulateFields(blobFields);
272
+ return endBlobAccumulator;
252
273
  },
253
274
  );
254
275
 
255
276
  export const buildHeaderFromCircuitOutputs = runInSpan(
256
277
  'BlockBuilderHelpers',
257
278
  'buildHeaderFromCircuitOutputs',
258
- async (
259
- _span,
260
- previousRollupData: BaseOrMergeRollupPublicInputs[],
261
- parityPublicInputs: ParityPublicInputs,
262
- rootRollupOutputs: BlockRootOrBlockMergePublicInputs,
263
- endState: StateReference,
264
- logger?: Logger,
265
- ) => {
266
- if (previousRollupData.length > 2) {
267
- throw new Error(`There can't be more than 2 previous rollups. Received ${previousRollupData.length}.`);
268
- }
279
+ async (_span, blockRootRollupOutput: BlockRollupPublicInputs) => {
280
+ const constants = blockRootRollupOutput.constants;
281
+ const globalVariables = GlobalVariables.from({
282
+ chainId: constants.chainId,
283
+ version: constants.version,
284
+ blockNumber: BlockNumber(blockRootRollupOutput.previousArchive.nextAvailableLeafIndex),
285
+ timestamp: blockRootRollupOutput.timestamp,
286
+ slotNumber: constants.slotNumber,
287
+ coinbase: constants.coinbase,
288
+ feeRecipient: constants.feeRecipient,
289
+ gasFees: constants.gasFees,
290
+ });
269
291
 
270
- const blobsHash = rootRollupOutputs.blobPublicInputs[0].getBlobsHash();
271
- const numTxs = previousRollupData.reduce((sum, d) => sum + d.numTxs, 0);
272
- const outHash =
273
- previousRollupData.length === 0
274
- ? Fr.ZERO.toBuffer()
275
- : previousRollupData.length === 1
276
- ? previousRollupData[0].outHash.toBuffer()
277
- : sha256Trunc(
278
- Buffer.concat([previousRollupData[0].outHash.toBuffer(), previousRollupData[1].outHash.toBuffer()]),
279
- );
280
- const contentCommitment = new ContentCommitment(
281
- new Fr(numTxs),
282
- blobsHash,
283
- parityPublicInputs.shaRoot.toBuffer(),
284
- outHash,
285
- );
292
+ const spongeBlobHash = await blockRootRollupOutput.endSpongeBlob.clone().squeeze();
286
293
 
287
- const accumulatedFees = previousRollupData.reduce((sum, d) => sum.add(d.accumulatedFees), Fr.ZERO);
288
- const accumulatedManaUsed = previousRollupData.reduce((sum, d) => sum.add(d.accumulatedManaUsed), Fr.ZERO);
289
- const header = new BlockHeader(
290
- rootRollupOutputs.previousArchive,
291
- contentCommitment,
292
- endState,
293
- rootRollupOutputs.endGlobalVariables,
294
- accumulatedFees,
295
- accumulatedManaUsed,
294
+ return new BlockHeader(
295
+ blockRootRollupOutput.previousArchive,
296
+ blockRootRollupOutput.endState,
297
+ spongeBlobHash,
298
+ globalVariables,
299
+ blockRootRollupOutput.accumulatedFees,
300
+ blockRootRollupOutput.accumulatedManaUsed,
296
301
  );
297
- if (!(await header.hash()).equals(rootRollupOutputs.endBlockHash)) {
298
- logger?.error(
299
- `Block header mismatch when building header from circuit outputs.` +
300
- `\n\nHeader: ${inspect(header)}` +
301
- `\n\nCircuit: ${toFriendlyJSON(rootRollupOutputs)}`,
302
- );
303
- throw new Error(`Block header mismatch when building from circuit outputs`);
304
- }
305
- return header;
306
302
  },
307
303
  );
308
304
 
@@ -312,111 +308,72 @@ export const buildHeaderAndBodyFromTxs = runInSpan(
312
308
  async (
313
309
  span,
314
310
  txs: ProcessedTx[],
311
+ lastArchive: AppendOnlyTreeSnapshot,
312
+ endState: StateReference,
315
313
  globalVariables: GlobalVariables,
316
- l1ToL2Messages: Fr[],
317
- db: MerkleTreeReadOperations,
314
+ startSpongeBlob: SpongeBlob,
315
+ isFirstBlock: boolean,
318
316
  ) => {
319
- span.setAttribute(Attributes.BLOCK_NUMBER, globalVariables.blockNumber.toNumber());
320
- const stateReference = new StateReference(
321
- await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db),
322
- new PartialStateReference(
323
- await getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE, db),
324
- await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE, db),
325
- await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE, db),
326
- ),
327
- );
328
-
329
- const previousArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
317
+ span.setAttribute(Attributes.BLOCK_NUMBER, globalVariables.blockNumber);
330
318
 
331
319
  const txEffects = txs.map(tx => tx.txEffect);
332
320
  const body = new Body(txEffects);
333
321
 
334
- const numTxs = body.txEffects.length;
335
- const outHash =
336
- numTxs === 0
337
- ? Fr.ZERO.toBuffer()
338
- : numTxs === 1
339
- ? body.txEffects[0].txOutHash()
340
- : computeUnbalancedMerkleRoot(
341
- body.txEffects.map(tx => tx.txOutHash()),
342
- TxEffect.empty().txOutHash(),
343
- );
322
+ const totalFees = txEffects.reduce((acc, tx) => acc.add(tx.transactionFee), Fr.ZERO);
323
+ const totalManaUsed = txs.reduce((acc, tx) => acc.add(new Fr(tx.gasUsed.billedGas.l2Gas)), Fr.ZERO);
344
324
 
345
- l1ToL2Messages = padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
346
- const hasher = (left: Buffer, right: Buffer) => Promise.resolve(sha256Trunc(Buffer.concat([left, right])));
347
- const parityHeight = Math.ceil(Math.log2(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP));
348
- const parityCalculator = await MerkleTreeCalculator.create(parityHeight, Fr.ZERO.toBuffer(), hasher);
349
- const parityShaRoot = await parityCalculator.computeTreeRoot(l1ToL2Messages.map(msg => msg.toBuffer()));
350
- const blobsHash = getBlobsHashFromBlobs(await Blob.getBlobs(body.toBlobFields()));
325
+ const { l1ToL2MessageTree, partial } = endState;
351
326
 
352
- const contentCommitment = new ContentCommitment(new Fr(numTxs), blobsHash, parityShaRoot, outHash);
327
+ const blockBlobFields = encodeBlockBlobData({
328
+ blockEndMarker: {
329
+ timestamp: globalVariables.timestamp,
330
+ blockNumber: globalVariables.blockNumber,
331
+ numTxs: txs.length,
332
+ },
333
+ blockEndStateField: {
334
+ l1ToL2MessageNextAvailableLeafIndex: l1ToL2MessageTree.nextAvailableLeafIndex,
335
+ noteHashNextAvailableLeafIndex: partial.noteHashTree.nextAvailableLeafIndex,
336
+ nullifierNextAvailableLeafIndex: partial.nullifierTree.nextAvailableLeafIndex,
337
+ publicDataNextAvailableLeafIndex: partial.publicDataTree.nextAvailableLeafIndex,
338
+ totalManaUsed: totalManaUsed.toBigInt(),
339
+ },
340
+ lastArchiveRoot: lastArchive.root,
341
+ noteHashRoot: partial.noteHashTree.root,
342
+ nullifierRoot: partial.nullifierTree.root,
343
+ publicDataRoot: partial.publicDataTree.root,
344
+ l1ToL2MessageRoot: isFirstBlock ? l1ToL2MessageTree.root : undefined,
345
+ txs: body.toTxBlobData(),
346
+ });
353
347
 
354
- const fees = body.txEffects.reduce((acc, tx) => acc.add(tx.transactionFee), Fr.ZERO);
355
- const manaUsed = txs.reduce((acc, tx) => acc.add(new Fr(tx.gasUsed.billedGas.l2Gas)), Fr.ZERO);
348
+ const endSpongeBlob = startSpongeBlob.clone();
349
+ await endSpongeBlob.absorb(blockBlobFields);
350
+ const spongeBlobHash = await endSpongeBlob.squeeze();
356
351
 
357
- const header = new BlockHeader(previousArchive, contentCommitment, stateReference, globalVariables, fees, manaUsed);
352
+ const header = BlockHeader.from({
353
+ lastArchive,
354
+ state: endState,
355
+ spongeBlobHash,
356
+ globalVariables,
357
+ totalFees,
358
+ totalManaUsed,
359
+ });
358
360
 
359
- return { header, body };
361
+ return { header, body, blockBlobFields };
360
362
  },
361
363
  );
362
364
 
363
- export function getBlobsHashFromBlobs(inputs: Blob[]): Buffer {
364
- const blobHashes = serializeToBuffer(inputs.map(b => b.getEthVersionedBlobHash()));
365
- return sha256Trunc(serializeToBuffer(blobHashes));
366
- }
367
-
368
- // Validate that the roots of all local trees match the output of the root circuit simulation
369
- export async function validateBlockRootOutput(
370
- blockRootOutput: BlockRootOrBlockMergePublicInputs,
371
- blockHeader: BlockHeader,
372
- db: MerkleTreeReadOperations,
373
- ) {
374
- await Promise.all([
375
- validateState(blockHeader.state, db),
376
- validateSimulatedTree(await getTreeSnapshot(MerkleTreeId.ARCHIVE, db), blockRootOutput.newArchive, 'Archive'),
377
- ]);
365
+ export async function getLastSiblingPath<TID extends MerkleTreeId>(treeId: TID, db: MerkleTreeReadOperations) {
366
+ const { size } = await db.getTreeInfo(treeId);
367
+ const path = await db.getSiblingPath(treeId, size - 1n);
368
+ return padArrayEnd(path.toFields(), Fr.ZERO, getTreeHeight(treeId));
378
369
  }
379
370
 
380
- export const validateState = runInSpan(
381
- 'BlockBuilderHelpers',
382
- 'validateState',
383
- async (_span, state: StateReference, db: MerkleTreeReadOperations) => {
384
- const promises = [MerkleTreeId.NOTE_HASH_TREE, MerkleTreeId.NULLIFIER_TREE, MerkleTreeId.PUBLIC_DATA_TREE].map(
385
- async (id: MerkleTreeId) => {
386
- return { key: id, value: await getTreeSnapshot(id, db) };
387
- },
388
- );
389
- const snapshots: Map<MerkleTreeId, AppendOnlyTreeSnapshot> = new Map(
390
- (await Promise.all(promises)).map(obj => [obj.key, obj.value]),
391
- );
392
- validatePartialState(state.partial, snapshots);
393
- validateSimulatedTree(
394
- await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db),
395
- state.l1ToL2MessageTree,
396
- 'L1ToL2MessageTree',
397
- );
398
- },
399
- );
400
-
401
371
  export async function getRootTreeSiblingPath<TID extends MerkleTreeId>(treeId: TID, db: MerkleTreeReadOperations) {
402
372
  const { size } = await db.getTreeInfo(treeId);
403
373
  const path = await db.getSiblingPath(treeId, size);
404
374
  return padArrayEnd(path.toFields(), Fr.ZERO, getTreeHeight(treeId));
405
375
  }
406
376
 
407
- export const getConstantRollupData = runInSpan(
408
- 'BlockBuilderHelpers',
409
- 'getConstantRollupData',
410
- async (_span, globalVariables: GlobalVariables, db: MerkleTreeReadOperations): Promise<ConstantRollupData> => {
411
- return ConstantRollupData.from({
412
- vkTreeRoot: getVKTreeRoot(),
413
- protocolContractTreeRoot,
414
- lastArchive: await getTreeSnapshot(MerkleTreeId.ARCHIVE, db),
415
- globalVariables,
416
- });
417
- },
418
- );
419
-
420
377
  export async function getTreeSnapshot(id: MerkleTreeId, db: MerkleTreeReadOperations): Promise<AppendOnlyTreeSnapshot> {
421
378
  const treeInfo = await db.getTreeInfo(id);
422
379
  return new AppendOnlyTreeSnapshot(Fr.fromBuffer(treeInfo.root), Number(treeInfo.size));
@@ -430,48 +387,6 @@ export function makeEmptyMembershipWitness<N extends number>(height: N) {
430
387
  );
431
388
  }
432
389
 
433
- const processPublicDataUpdateRequests = runInSpan(
434
- 'BlockBuilderHelpers',
435
- 'processPublicDataUpdateRequests',
436
- async (span, tx: ProcessedTx, db: MerkleTreeWriteOperations) => {
437
- span.setAttribute(Attributes.TX_HASH, tx.hash.toString());
438
- const allPublicDataWrites = tx.txEffect.publicDataWrites.map(
439
- ({ leafSlot, value }) => new PublicDataTreeLeaf(leafSlot, value),
440
- );
441
-
442
- const { lowLeavesWitnessData, insertionWitnessData } = await db.sequentialInsert(
443
- MerkleTreeId.PUBLIC_DATA_TREE,
444
- allPublicDataWrites.map(write => {
445
- if (write.isEmpty()) {
446
- throw new Error(`Empty public data write in tx: ${toFriendlyJSON(tx)}`);
447
- }
448
- return write.toBuffer();
449
- }),
450
- );
451
-
452
- const lowPublicDataWritesPreimages = lowLeavesWitnessData.map(
453
- lowLeafWitness => lowLeafWitness.leafPreimage as PublicDataTreeLeafPreimage,
454
- );
455
- const lowPublicDataWritesMembershipWitnesses = lowLeavesWitnessData.map(lowLeafWitness =>
456
- MembershipWitness.fromBufferArray<typeof PUBLIC_DATA_TREE_HEIGHT>(
457
- lowLeafWitness.index,
458
- assertLength(lowLeafWitness.siblingPath.toBufferArray(), PUBLIC_DATA_TREE_HEIGHT),
459
- ),
460
- );
461
- const publicDataWritesSiblingPaths = insertionWitnessData.map(w => {
462
- const insertionSiblingPath = w.siblingPath.toFields();
463
- assertLength(insertionSiblingPath, PUBLIC_DATA_TREE_HEIGHT);
464
- return insertionSiblingPath as Tuple<Fr, typeof PUBLIC_DATA_TREE_HEIGHT>;
465
- });
466
-
467
- return {
468
- lowPublicDataWritesPreimages,
469
- lowPublicDataWritesMembershipWitnesses,
470
- publicDataWritesSiblingPaths,
471
- };
472
- },
473
- );
474
-
475
390
  export async function getSubtreeSiblingPath(
476
391
  treeId: MerkleTreeId,
477
392
  subtreeHeight: number,
@@ -537,17 +452,26 @@ function validateSimulatedTree(
537
452
  }
538
453
 
539
454
  export function validateTx(tx: ProcessedTx) {
540
- const txHeader = tx.constants.historicalHeader;
541
- if (txHeader.state.l1ToL2MessageTree.isZero()) {
455
+ const txHeader = tx.data.constants.anchorBlockHeader;
456
+ if (txHeader.state.l1ToL2MessageTree.isEmpty()) {
542
457
  throw new Error(`Empty L1 to L2 messages tree in tx: ${toFriendlyJSON(tx)}`);
543
458
  }
544
- if (txHeader.state.partial.noteHashTree.isZero()) {
459
+ if (txHeader.state.partial.noteHashTree.isEmpty()) {
545
460
  throw new Error(`Empty note hash tree in tx: ${toFriendlyJSON(tx)}`);
546
461
  }
547
- if (txHeader.state.partial.nullifierTree.isZero()) {
462
+ if (txHeader.state.partial.nullifierTree.isEmpty()) {
548
463
  throw new Error(`Empty nullifier tree in tx: ${toFriendlyJSON(tx)}`);
549
464
  }
550
- if (txHeader.state.partial.publicDataTree.isZero()) {
465
+ if (txHeader.state.partial.publicDataTree.isEmpty()) {
551
466
  throw new Error(`Empty public data tree in tx: ${toFriendlyJSON(tx)}`);
552
467
  }
553
468
  }
469
+
470
+ export function toProofData<T extends Bufferable, PROOF_LENGTH extends number>(
471
+ { inputs, proof, verificationKey }: PublicInputsAndRecursiveProof<T, PROOF_LENGTH>,
472
+ vkIndex?: number,
473
+ ) {
474
+ const leafIndex = vkIndex || getVKIndex(verificationKey.keyAsFields);
475
+ const vkData = new VkData(verificationKey, leafIndex, getVKSiblingPath(leafIndex));
476
+ return new ProofData(inputs, proof, vkData);
477
+ }