@aztec/prover-client 0.69.1 → 0.71.0

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 (130) hide show
  1. package/dest/bin/get-proof-inputs.d.ts +2 -0
  2. package/dest/bin/get-proof-inputs.d.ts.map +1 -0
  3. package/dest/bin/get-proof-inputs.js +50 -0
  4. package/dest/block_builder/light.d.ts +3 -5
  5. package/dest/block_builder/light.d.ts.map +1 -1
  6. package/dest/block_builder/light.js +9 -22
  7. package/dest/config.d.ts +2 -1
  8. package/dest/config.d.ts.map +1 -1
  9. package/dest/config.js +3 -2
  10. package/dest/mocks/fixtures.d.ts +1 -1
  11. package/dest/mocks/fixtures.d.ts.map +1 -1
  12. package/dest/mocks/fixtures.js +2 -2
  13. package/dest/mocks/test_context.d.ts +1 -1
  14. package/dest/mocks/test_context.d.ts.map +1 -1
  15. package/dest/mocks/test_context.js +11 -12
  16. package/dest/orchestrator/block-building-helpers.d.ts +15 -29
  17. package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
  18. package/dest/orchestrator/block-building-helpers.js +51 -58
  19. package/dest/orchestrator/block-proving-state.d.ts +40 -44
  20. package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
  21. package/dest/orchestrator/block-proving-state.js +149 -85
  22. package/dest/orchestrator/epoch-proving-state.d.ts +23 -30
  23. package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
  24. package/dest/orchestrator/epoch-proving-state.js +92 -65
  25. package/dest/orchestrator/orchestrator.d.ts +17 -48
  26. package/dest/orchestrator/orchestrator.d.ts.map +1 -1
  27. package/dest/orchestrator/orchestrator.js +208 -351
  28. package/dest/orchestrator/tx-proving-state.d.ts +10 -6
  29. package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
  30. package/dest/orchestrator/tx-proving-state.js +57 -46
  31. package/dest/prover-agent/memory-proving-queue.d.ts +4 -4
  32. package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
  33. package/dest/prover-agent/memory-proving-queue.js +5 -5
  34. package/dest/prover-agent/prover-agent.d.ts +0 -2
  35. package/dest/prover-agent/prover-agent.d.ts.map +1 -1
  36. package/dest/prover-agent/prover-agent.js +7 -9
  37. package/dest/prover-client/factory.d.ts.map +1 -1
  38. package/dest/prover-client/factory.js +3 -3
  39. package/dest/prover-client/prover-client.d.ts +4 -2
  40. package/dest/prover-client/prover-client.d.ts.map +1 -1
  41. package/dest/prover-client/prover-client.js +16 -15
  42. package/dest/prover-client/server-epoch-prover.d.ts +25 -0
  43. package/dest/prover-client/server-epoch-prover.d.ts.map +1 -0
  44. package/dest/prover-client/server-epoch-prover.js +40 -0
  45. package/dest/proving_broker/broker_prover_facade.d.ts +19 -7
  46. package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
  47. package/dest/proving_broker/broker_prover_facade.js +271 -49
  48. package/dest/proving_broker/config.d.ts +61 -0
  49. package/dest/proving_broker/config.d.ts.map +1 -0
  50. package/dest/proving_broker/config.js +83 -0
  51. package/dest/proving_broker/factory.d.ts +1 -1
  52. package/dest/proving_broker/factory.d.ts.map +1 -1
  53. package/dest/proving_broker/factory.js +4 -7
  54. package/dest/proving_broker/fixtures.d.ts +5 -0
  55. package/dest/proving_broker/fixtures.d.ts.map +1 -0
  56. package/dest/proving_broker/fixtures.js +12 -0
  57. package/dest/proving_broker/index.d.ts +2 -1
  58. package/dest/proving_broker/index.d.ts.map +1 -1
  59. package/dest/proving_broker/index.js +3 -2
  60. package/dest/proving_broker/proof_store/factory.d.ts +6 -0
  61. package/dest/proving_broker/proof_store/factory.d.ts.map +1 -0
  62. package/dest/proving_broker/proof_store/factory.js +39 -0
  63. package/dest/proving_broker/proof_store/gcs_proof_store.d.ts +13 -0
  64. package/dest/proving_broker/proof_store/gcs_proof_store.d.ts.map +1 -0
  65. package/dest/proving_broker/proof_store/gcs_proof_store.js +46 -0
  66. package/dest/proving_broker/proof_store/index.d.ts +4 -0
  67. package/dest/proving_broker/proof_store/index.d.ts.map +1 -0
  68. package/dest/proving_broker/proof_store/index.js +4 -0
  69. package/dest/proving_broker/proof_store/inline_proof_store.d.ts +14 -0
  70. package/dest/proving_broker/proof_store/inline_proof_store.d.ts.map +1 -0
  71. package/dest/proving_broker/proof_store/inline_proof_store.js +37 -0
  72. package/dest/proving_broker/{proof_store.d.ts → proof_store/proof_store.d.ts} +1 -12
  73. package/dest/proving_broker/proof_store/proof_store.d.ts.map +1 -0
  74. package/dest/proving_broker/proof_store/proof_store.js +2 -0
  75. package/dest/proving_broker/proving_agent.d.ts +4 -4
  76. package/dest/proving_broker/proving_agent.d.ts.map +1 -1
  77. package/dest/proving_broker/proving_agent.js +5 -5
  78. package/dest/proving_broker/proving_broker.d.ts +16 -12
  79. package/dest/proving_broker/proving_broker.d.ts.map +1 -1
  80. package/dest/proving_broker/proving_broker.js +307 -274
  81. package/dest/proving_broker/proving_broker_database/memory.d.ts +4 -2
  82. package/dest/proving_broker/proving_broker_database/memory.d.ts.map +1 -1
  83. package/dest/proving_broker/proving_broker_database/memory.js +17 -4
  84. package/dest/proving_broker/proving_broker_database/persisted.d.ts +10 -6
  85. package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -1
  86. package/dest/proving_broker/proving_broker_database/persisted.js +106 -14
  87. package/dest/proving_broker/proving_broker_database.d.ts +7 -3
  88. package/dest/proving_broker/proving_broker_database.d.ts.map +1 -1
  89. package/dest/proving_broker/proving_job_controller.js +4 -4
  90. package/dest/proving_broker/rpc.d.ts.map +1 -1
  91. package/dest/proving_broker/rpc.js +4 -4
  92. package/dest/test/mock_prover.d.ts +8 -8
  93. package/dest/test/mock_prover.d.ts.map +1 -1
  94. package/dest/test/mock_prover.js +9 -10
  95. package/package.json +14 -12
  96. package/src/bin/get-proof-inputs.ts +60 -0
  97. package/src/block_builder/light.ts +7 -31
  98. package/src/config.ts +4 -4
  99. package/src/mocks/fixtures.ts +1 -1
  100. package/src/mocks/test_context.ts +9 -11
  101. package/src/orchestrator/block-building-helpers.ts +360 -402
  102. package/src/orchestrator/block-proving-state.ts +251 -121
  103. package/src/orchestrator/epoch-proving-state.ts +159 -88
  104. package/src/orchestrator/orchestrator.ts +262 -542
  105. package/src/orchestrator/tx-proving-state.ts +30 -18
  106. package/src/prover-agent/memory-proving-queue.ts +12 -16
  107. package/src/prover-agent/prover-agent.ts +14 -8
  108. package/src/prover-client/factory.ts +2 -3
  109. package/src/prover-client/prover-client.ts +17 -20
  110. package/src/prover-client/server-epoch-prover.ts +44 -0
  111. package/src/proving_broker/broker_prover_facade.ts +347 -67
  112. package/src/proving_broker/config.ts +93 -0
  113. package/src/proving_broker/factory.ts +11 -10
  114. package/src/proving_broker/fixtures.ts +14 -0
  115. package/src/proving_broker/index.ts +2 -1
  116. package/src/proving_broker/proof_store/factory.ts +42 -0
  117. package/src/proving_broker/proof_store/gcs_proof_store.ts +72 -0
  118. package/src/proving_broker/proof_store/index.ts +3 -0
  119. package/src/proving_broker/{proof_store.ts → proof_store/inline_proof_store.ts} +1 -44
  120. package/src/proving_broker/proof_store/proof_store.ts +54 -0
  121. package/src/proving_broker/proving_agent.ts +11 -5
  122. package/src/proving_broker/proving_broker.ts +122 -73
  123. package/src/proving_broker/proving_broker_database/memory.ts +24 -4
  124. package/src/proving_broker/proving_broker_database/persisted.ts +142 -20
  125. package/src/proving_broker/proving_broker_database.ts +8 -3
  126. package/src/proving_broker/proving_job_controller.ts +5 -5
  127. package/src/proving_broker/rpc.ts +2 -3
  128. package/src/test/mock_prover.ts +12 -18
  129. package/dest/proving_broker/proof_store.d.ts.map +0 -1
  130. package/dest/proving_broker/proof_store.js +0 -37
@@ -1,36 +1,48 @@
1
- import { type L2Block, type MerkleTreeId } from '@aztec/circuit-types';
1
+ import { type L2Block, type MerkleTreeId, type PublicInputsAndRecursiveProof } from '@aztec/circuit-types';
2
+ import { type CircuitName } from '@aztec/circuit-types/stats';
2
3
  import {
3
4
  type ARCHIVE_HEIGHT,
4
5
  type AppendOnlyTreeSnapshot,
5
- type Fr,
6
+ BLOBS_PER_BLOCK,
7
+ type BlockHeader,
8
+ FIELDS_PER_BLOB,
9
+ Fr,
6
10
  type GlobalVariables,
7
11
  type L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH,
8
- type NESTED_RECURSIVE_PROOF_LENGTH,
12
+ MembershipWitness,
9
13
  type NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
10
14
  type NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
11
15
  NUM_BASE_PARITY_PER_ROOT_PARITY,
12
- type Proof,
16
+ type ParityPublicInputs,
13
17
  type RECURSIVE_PROOF_LENGTH,
14
- type RecursiveProof,
15
- type RootParityInput,
16
- type VerificationKeyAsFields,
18
+ RootParityInput,
19
+ RootParityInputs,
20
+ StateReference,
21
+ VK_TREE_HEIGHT,
17
22
  } from '@aztec/circuits.js';
18
23
  import { SpongeBlob } from '@aztec/circuits.js/blobs';
19
- import { type BaseOrMergeRollupPublicInputs, type BlockRootOrBlockMergePublicInputs } from '@aztec/circuits.js/rollup';
24
+ import {
25
+ type BaseOrMergeRollupPublicInputs,
26
+ type BlockRootOrBlockMergePublicInputs,
27
+ BlockRootRollupData,
28
+ BlockRootRollupInputs,
29
+ ConstantRollupData,
30
+ EmptyBlockRootRollupInputs,
31
+ MergeRollupInputs,
32
+ PreviousRollupData,
33
+ SingleTxBlockRootRollupInputs,
34
+ } from '@aztec/circuits.js/rollup';
35
+ import { padArrayEnd } from '@aztec/foundation/collection';
36
+ import { type Logger } from '@aztec/foundation/log';
20
37
  import { type Tuple } from '@aztec/foundation/serialize';
38
+ import { type TreeNodeLocation, UnbalancedTreeStore } from '@aztec/foundation/trees';
39
+ import { getVKIndex, getVKSiblingPath, getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks';
40
+ import { protocolContractTreeRoot } from '@aztec/protocol-contracts';
21
41
 
42
+ import { buildBlobHints, buildHeaderFromCircuitOutputs } from './block-building-helpers.js';
22
43
  import { type EpochProvingState } from './epoch-proving-state.js';
23
44
  import { type TxProvingState } from './tx-proving-state.js';
24
45
 
25
- export type MergeRollupInputData = {
26
- inputs: [BaseOrMergeRollupPublicInputs | undefined, BaseOrMergeRollupPublicInputs | undefined];
27
- proofs: [
28
- RecursiveProof<typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH> | undefined,
29
- RecursiveProof<typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH> | undefined,
30
- ];
31
- verificationKeys: [VerificationKeyAsFields | undefined, VerificationKeyAsFields | undefined];
32
- };
33
-
34
46
  export type TreeSnapshots = Map<MerkleTreeId, AppendOnlyTreeSnapshot>;
35
47
 
36
48
  /**
@@ -38,12 +50,15 @@ export type TreeSnapshots = Map<MerkleTreeId, AppendOnlyTreeSnapshot>;
38
50
  * Contains the raw inputs and intermediate state to generate every constituent proof in the tree.
39
51
  */
40
52
  export class BlockProvingState {
41
- private mergeRollupInputs: MergeRollupInputData[] = [];
42
- private rootParityInputs: Array<RootParityInput<typeof RECURSIVE_PROOF_LENGTH> | undefined> = [];
43
- private finalRootParityInputs: RootParityInput<typeof NESTED_RECURSIVE_PROOF_LENGTH> | undefined;
44
- public blockRootRollupPublicInputs: BlockRootOrBlockMergePublicInputs | undefined;
53
+ private baseOrMergeProvingOutputs: UnbalancedTreeStore<
54
+ PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
55
+ > = new UnbalancedTreeStore(0);
56
+ private baseParityProvingOutputs: (PublicInputsAndRecursiveProof<ParityPublicInputs> | undefined)[];
57
+ private rootParityProvingOutput: PublicInputsAndRecursiveProof<ParityPublicInputs> | undefined;
58
+ private blockRootProvingOutput:
59
+ | PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
60
+ | undefined;
45
61
  public blockRootRollupStarted: boolean = false;
46
- public finalProof: Proof | undefined;
47
62
  public block: L2Block | undefined;
48
63
  public spongeBlobState: SpongeBlob | undefined;
49
64
  public totalNumTxs: number;
@@ -54,15 +69,16 @@ export class BlockProvingState {
54
69
  public readonly index: number,
55
70
  public readonly globalVariables: GlobalVariables,
56
71
  public readonly newL1ToL2Messages: Tuple<Fr, typeof NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP>,
57
- public readonly messageTreeSnapshot: AppendOnlyTreeSnapshot,
58
- public readonly messageTreeRootSiblingPath: Tuple<Fr, typeof L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH>,
59
- public readonly messageTreeSnapshotAfterInsertion: AppendOnlyTreeSnapshot,
60
- public readonly archiveTreeSnapshot: AppendOnlyTreeSnapshot,
61
- public readonly archiveTreeRootSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>,
62
- public readonly previousBlockHash: Fr,
72
+ private readonly messageTreeSnapshot: AppendOnlyTreeSnapshot,
73
+ private readonly messageTreeRootSiblingPath: Tuple<Fr, typeof L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH>,
74
+ private readonly messageTreeSnapshotAfterInsertion: AppendOnlyTreeSnapshot,
75
+ private readonly archiveTreeSnapshot: AppendOnlyTreeSnapshot,
76
+ private readonly archiveTreeRootSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>,
77
+ private readonly previousBlockHeader: BlockHeader,
78
+ private readonly previousBlockHash: Fr,
63
79
  private readonly parentEpoch: EpochProvingState,
64
80
  ) {
65
- this.rootParityInputs = Array.from({ length: NUM_BASE_PARITY_PER_ROOT_PARITY }).map(_ => undefined);
81
+ this.baseParityProvingOutputs = Array.from({ length: NUM_BASE_PARITY_PER_ROOT_PARITY }).map(_ => undefined);
66
82
  this.totalNumTxs = 0;
67
83
  }
68
84
 
@@ -70,41 +86,12 @@ export class BlockProvingState {
70
86
  return this.globalVariables.blockNumber.toNumber();
71
87
  }
72
88
 
73
- // Returns the number of levels of merge rollups
74
- public get numMergeLevels() {
75
- return BigInt(Math.ceil(Math.log2(this.totalNumTxs)) - 1);
76
- }
77
-
78
- // Calculates the index and level of the parent rollup circuit
79
- // Based on tree implementation in unbalanced_tree.ts -> batchInsert()
80
- public findMergeLevel(currentLevel: bigint, currentIndex: bigint) {
81
- const moveUpMergeLevel = (levelSize: number, index: bigint, nodeToShift: boolean) => {
82
- levelSize /= 2;
83
- if (levelSize & 1) {
84
- [levelSize, nodeToShift] = nodeToShift ? [levelSize + 1, false] : [levelSize - 1, true];
85
- }
86
- index >>= 1n;
87
- return { thisLevelSize: levelSize, thisIndex: index, shiftUp: nodeToShift };
88
- };
89
- let [thisLevelSize, shiftUp] = this.totalNumTxs & 1 ? [this.totalNumTxs - 1, true] : [this.totalNumTxs, false];
90
- const maxLevel = this.numMergeLevels + 1n;
91
- let placeholder = currentIndex;
92
- for (let i = 0; i < maxLevel - currentLevel; i++) {
93
- ({ thisLevelSize, thisIndex: placeholder, shiftUp } = moveUpMergeLevel(thisLevelSize, placeholder, shiftUp));
94
- }
95
- let thisIndex = currentIndex;
96
- let mergeLevel = currentLevel;
97
- while (thisIndex >= thisLevelSize && mergeLevel != 0n) {
98
- mergeLevel -= 1n;
99
- ({ thisLevelSize, thisIndex, shiftUp } = moveUpMergeLevel(thisLevelSize, thisIndex, shiftUp));
100
- }
101
- return [mergeLevel - 1n, thisIndex >> 1n, thisIndex & 1n];
102
- }
103
-
104
89
  public startNewBlock(numTxs: number, numBlobFields: number) {
105
90
  if (this.spongeBlobState) {
106
91
  throw new Error(`Block ${this.blockNumber} already initalised.`);
107
92
  }
93
+
94
+ this.baseOrMergeProvingOutputs = new UnbalancedTreeStore(numTxs);
108
95
  // Initialise the sponge which will eventually absorb all tx effects to be added to the blob.
109
96
  // Like l1 to l2 messages, we need to know beforehand how many effects will be absorbed.
110
97
  this.spongeBlobState = SpongeBlob.init(numBlobFields);
@@ -116,28 +103,53 @@ export class BlockProvingState {
116
103
  if (!this.spongeBlobState) {
117
104
  throw new Error(`Invalid block proving state, call startNewBlock before adding transactions.`);
118
105
  }
119
- this.txs.push(tx);
120
- return this.txs.length - 1;
106
+
107
+ const txIndex = this.txs.length;
108
+ this.txs[txIndex] = tx;
109
+ return txIndex;
121
110
  }
122
111
 
123
- // Returns the number of received transactions
124
- public get transactionsReceived() {
125
- return this.txs.length;
112
+ public setBaseRollupProof(
113
+ txIndex: number,
114
+ provingOutput: PublicInputsAndRecursiveProof<
115
+ BaseOrMergeRollupPublicInputs,
116
+ typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
117
+ >,
118
+ ): TreeNodeLocation {
119
+ return this.baseOrMergeProvingOutputs.setLeaf(txIndex, provingOutput);
126
120
  }
127
121
 
128
- // Returns the final set of root parity inputs
129
- public get finalRootParityInput() {
130
- return this.finalRootParityInputs;
122
+ public setMergeRollupProof(
123
+ location: TreeNodeLocation,
124
+ provingOutput: PublicInputsAndRecursiveProof<
125
+ BaseOrMergeRollupPublicInputs,
126
+ typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
127
+ >,
128
+ ) {
129
+ this.baseOrMergeProvingOutputs.setNode(location, provingOutput);
131
130
  }
132
131
 
133
- // Sets the final set of root parity inputs
134
- public set finalRootParityInput(input: RootParityInput<typeof NESTED_RECURSIVE_PROOF_LENGTH> | undefined) {
135
- this.finalRootParityInputs = input;
132
+ // Stores a set of root parity inputs at the given index
133
+ public setBaseParityProof(index: number, provingOutput: PublicInputsAndRecursiveProof<ParityPublicInputs>) {
134
+ if (index >= NUM_BASE_PARITY_PER_ROOT_PARITY) {
135
+ throw new Error(
136
+ `Unable to set a base parity proofs at index ${index}. Expected at most ${NUM_BASE_PARITY_PER_ROOT_PARITY} proofs.`,
137
+ );
138
+ }
139
+ this.baseParityProvingOutputs[index] = provingOutput;
136
140
  }
137
141
 
138
- // Returns the set of root parity inputs
139
- public get rootParityInput() {
140
- return this.rootParityInputs;
142
+ public setRootParityProof(provingOutput: PublicInputsAndRecursiveProof<ParityPublicInputs>) {
143
+ this.rootParityProvingOutput = provingOutput;
144
+ }
145
+
146
+ public setBlockRootRollupProof(
147
+ provingOutput: PublicInputsAndRecursiveProof<
148
+ BlockRootOrBlockMergePublicInputs,
149
+ typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
150
+ >,
151
+ ) {
152
+ this.blockRootProvingOutput = provingOutput;
141
153
  }
142
154
 
143
155
  // Returns the complete set of transaction proving state objects
@@ -150,39 +162,66 @@ export class BlockProvingState {
150
162
  return this.parentEpoch.epochNumber;
151
163
  }
152
164
 
153
- /**
154
- * Stores the inputs to a merge circuit and determines if the circuit is ready to be executed
155
- * @param mergeInputs - The inputs to store
156
- * @param indexWithinMerge - The index in the set of inputs to this merge circuit
157
- * @param indexOfMerge - The global index of this merge circuit
158
- * @returns True if the merge circuit is ready to be executed, false otherwise
159
- */
160
- public storeMergeInputs(
161
- mergeInputs: [
162
- BaseOrMergeRollupPublicInputs,
163
- RecursiveProof<typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>,
164
- VerificationKeyAsFields,
165
- ],
166
- indexWithinMerge: number,
167
- indexOfMerge: number,
168
- ) {
169
- if (!this.mergeRollupInputs[indexOfMerge]) {
170
- const mergeInputData: MergeRollupInputData = {
171
- inputs: [undefined, undefined],
172
- proofs: [undefined, undefined],
173
- verificationKeys: [undefined, undefined],
165
+ public getParentLocation(location: TreeNodeLocation) {
166
+ return this.baseOrMergeProvingOutputs.getParentLocation(location);
167
+ }
168
+
169
+ public getMergeRollupInputs(mergeLocation: TreeNodeLocation) {
170
+ const [left, right] = this.baseOrMergeProvingOutputs.getChildren(mergeLocation);
171
+ if (!left || !right) {
172
+ throw new Error('At lease one child is not ready.');
173
+ }
174
+
175
+ return new MergeRollupInputs([this.#getPreviousRollupData(left), this.#getPreviousRollupData(right)]);
176
+ }
177
+
178
+ public getBlockRootRollupTypeAndInputs(proverId: Fr) {
179
+ if (this.totalNumTxs === 0) {
180
+ return {
181
+ rollupType: 'empty-block-root-rollup' satisfies CircuitName,
182
+ inputs: this.#getEmptyBlockRootInputs(proverId),
183
+ };
184
+ }
185
+
186
+ const proofs = this.#getChildProofsForBlockRoot();
187
+ const nonEmptyProofs = proofs.filter(p => !!p);
188
+ if (proofs.length !== nonEmptyProofs.length) {
189
+ throw new Error('At lease one child is not ready for the block root.');
190
+ }
191
+
192
+ const previousRollupData = nonEmptyProofs.map(p => this.#getPreviousRollupData(p!));
193
+ const data = this.#getBlockRootRollupData(proverId);
194
+
195
+ if (previousRollupData.length === 1) {
196
+ return {
197
+ rollupType: 'single-tx-block-root-rollup' satisfies CircuitName,
198
+ inputs: new SingleTxBlockRootRollupInputs(previousRollupData as [PreviousRollupData], data),
199
+ };
200
+ } else {
201
+ return {
202
+ rollupType: 'block-root-rollup' satisfies CircuitName,
203
+ inputs: new BlockRootRollupInputs(previousRollupData as [PreviousRollupData, PreviousRollupData], data),
174
204
  };
175
- mergeInputData.inputs[indexWithinMerge] = mergeInputs[0];
176
- mergeInputData.proofs[indexWithinMerge] = mergeInputs[1];
177
- mergeInputData.verificationKeys[indexWithinMerge] = mergeInputs[2];
178
- this.mergeRollupInputs[indexOfMerge] = mergeInputData;
179
- return false;
180
205
  }
181
- const mergeInputData = this.mergeRollupInputs[indexOfMerge];
182
- mergeInputData.inputs[indexWithinMerge] = mergeInputs[0];
183
- mergeInputData.proofs[indexWithinMerge] = mergeInputs[1];
184
- mergeInputData.verificationKeys[indexWithinMerge] = mergeInputs[2];
185
- return true;
206
+ }
207
+
208
+ public getRootParityInputs() {
209
+ if (!this.baseParityProvingOutputs.every(p => !!p)) {
210
+ throw new Error('At lease one base parity is not ready.');
211
+ }
212
+
213
+ const children = this.baseParityProvingOutputs.map(p => this.#getRootParityInputFromProvingOutput(p!));
214
+ return new RootParityInputs(
215
+ children as Tuple<RootParityInput<typeof RECURSIVE_PROOF_LENGTH>, typeof NUM_BASE_PARITY_PER_ROOT_PARITY>,
216
+ );
217
+ }
218
+
219
+ public getL1ToL2Roots() {
220
+ if (!this.rootParityProvingOutput) {
221
+ throw new Error('Root parity is not ready.');
222
+ }
223
+
224
+ return this.#getRootParityInputFromProvingOutput(this.rootParityProvingOutput);
186
225
  }
187
226
 
188
227
  // Returns a specific transaction proving state
@@ -190,29 +229,43 @@ export class BlockProvingState {
190
229
  return this.txs[txIndex];
191
230
  }
192
231
 
193
- // Returns a set of merge rollup inputs
194
- public getMergeInputs(indexOfMerge: number) {
195
- return this.mergeRollupInputs[indexOfMerge];
196
- }
232
+ public buildHeaderFromProvingOutputs(logger?: Logger) {
233
+ const previousRollupData =
234
+ this.totalNumTxs === 0 ? [] : this.#getChildProofsForBlockRoot().map(p => this.#getPreviousRollupData(p!));
197
235
 
198
- // Returns true if we have sufficient inputs to execute the block root rollup
199
- public isReadyForBlockRootRollup() {
200
- return !(
201
- this.block === undefined ||
202
- this.mergeRollupInputs[0] === undefined ||
203
- this.finalRootParityInput === undefined ||
204
- this.mergeRollupInputs[0].inputs.findIndex(p => !p) !== -1
236
+ let endPartialState = this.previousBlockHeader.state.partial;
237
+ if (this.totalNumTxs !== 0) {
238
+ const previousRollupData = this.#getChildProofsForBlockRoot();
239
+ const lastRollup = previousRollupData[previousRollupData.length - 1];
240
+ if (!lastRollup) {
241
+ throw new Error('End state of the block is not available. Last rollup is not ready yet.');
242
+ }
243
+ endPartialState = lastRollup.inputs.end;
244
+ }
245
+ const endState = new StateReference(this.messageTreeSnapshotAfterInsertion, endPartialState);
246
+
247
+ return buildHeaderFromCircuitOutputs(
248
+ previousRollupData.map(d => d.baseOrMergeRollupPublicInputs),
249
+ this.rootParityProvingOutput!.inputs,
250
+ this.blockRootProvingOutput!.inputs,
251
+ endState,
252
+ logger,
205
253
  );
206
254
  }
207
255
 
208
- // Stores a set of root parity inputs at the given index
209
- public setRootParityInputs(inputs: RootParityInput<typeof RECURSIVE_PROOF_LENGTH>, index: number) {
210
- this.rootParityInputs[index] = inputs;
256
+ public isReadyForMergeRollup(location: TreeNodeLocation) {
257
+ return this.baseOrMergeProvingOutputs.getSibling(location) !== undefined;
258
+ }
259
+
260
+ // Returns true if we have sufficient inputs to execute the block root rollup
261
+ public isReadyForBlockRootRollup() {
262
+ const childProofs = this.#getChildProofsForBlockRoot();
263
+ return this.block !== undefined && this.rootParityProvingOutput !== undefined && childProofs.every(p => !!p);
211
264
  }
212
265
 
213
266
  // Returns true if we have sufficient root parity inputs to execute the root parity circuit
214
- public areRootParityInputsReady() {
215
- return this.rootParityInputs.findIndex(p => !p) === -1;
267
+ public isReadyForRootParity() {
268
+ return this.baseParityProvingOutputs.every(p => !!p);
216
269
  }
217
270
 
218
271
  // Returns whether the proving state is still valid
@@ -224,4 +277,81 @@ export class BlockProvingState {
224
277
  this.error = reason;
225
278
  this.parentEpoch.reject(reason);
226
279
  }
280
+
281
+ #getEmptyBlockRootInputs(proverId: Fr) {
282
+ const l1ToL2Roots = this.getL1ToL2Roots();
283
+ const constants = ConstantRollupData.from({
284
+ lastArchive: this.archiveTreeSnapshot,
285
+ globalVariables: this.globalVariables,
286
+ vkTreeRoot: getVKTreeRoot(),
287
+ protocolContractTreeRoot,
288
+ });
289
+
290
+ return EmptyBlockRootRollupInputs.from({
291
+ l1ToL2Roots,
292
+ newL1ToL2MessageTreeRootSiblingPath: this.messageTreeRootSiblingPath,
293
+ startL1ToL2MessageTreeSnapshot: this.messageTreeSnapshot,
294
+ newArchiveSiblingPath: this.archiveTreeRootSiblingPath,
295
+ previousBlockHash: this.previousBlockHash,
296
+ previousPartialState: this.previousBlockHeader.state.partial,
297
+ constants,
298
+ proverId,
299
+ isPadding: false,
300
+ });
301
+ }
302
+
303
+ #getBlockRootRollupData(proverId: Fr) {
304
+ const txEffects = this.txs.map(txProvingState => txProvingState.processedTx.txEffect);
305
+ const { blobFields, blobCommitments, blobsHash } = buildBlobHints(txEffects);
306
+ return BlockRootRollupData.from({
307
+ l1ToL2Roots: this.getL1ToL2Roots(),
308
+ newL1ToL2MessageTreeRootSiblingPath: this.messageTreeRootSiblingPath,
309
+ startL1ToL2MessageTreeSnapshot: this.messageTreeSnapshot,
310
+ newArchiveSiblingPath: this.archiveTreeRootSiblingPath,
311
+ previousBlockHash: this.previousBlockHash,
312
+ proverId,
313
+ blobFields: padArrayEnd(blobFields, Fr.ZERO, FIELDS_PER_BLOB * BLOBS_PER_BLOCK),
314
+ blobCommitments: padArrayEnd(blobCommitments, [Fr.ZERO, Fr.ZERO], BLOBS_PER_BLOCK),
315
+ blobsHash,
316
+ });
317
+ }
318
+
319
+ #getChildProofsForBlockRoot() {
320
+ if (this.totalNumTxs === 0) {
321
+ return [];
322
+ }
323
+
324
+ const rootLocation = { level: 0, index: 0 };
325
+ // If there's only 1 tx, its base rollup proof will be stored at the root.
326
+ return this.totalNumTxs === 1
327
+ ? [this.baseOrMergeProvingOutputs.getNode(rootLocation)]
328
+ : this.baseOrMergeProvingOutputs.getChildren(rootLocation);
329
+ }
330
+
331
+ #getPreviousRollupData({
332
+ inputs,
333
+ proof,
334
+ verificationKey,
335
+ }: PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>) {
336
+ const leafIndex = getVKIndex(verificationKey.keyAsFields);
337
+ return new PreviousRollupData(
338
+ inputs,
339
+ proof,
340
+ verificationKey.keyAsFields,
341
+ new MembershipWitness(VK_TREE_HEIGHT, BigInt(leafIndex), getVKSiblingPath(leafIndex)),
342
+ );
343
+ }
344
+
345
+ #getRootParityInputFromProvingOutput({
346
+ inputs,
347
+ proof,
348
+ verificationKey,
349
+ }: PublicInputsAndRecursiveProof<ParityPublicInputs>) {
350
+ return new RootParityInput(
351
+ proof,
352
+ verificationKey.keyAsFields,
353
+ getVKSiblingPath(getVKIndex(verificationKey)),
354
+ inputs,
355
+ );
356
+ }
227
357
  }