@aztec/prover-client 0.0.0-test.1 → 0.0.1-commit.03f7ef2

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 (149) 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 +108 -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 +36 -0
  14. package/dest/light/lightweight_checkpoint_builder.d.ts.map +1 -0
  15. package/dest/light/lightweight_checkpoint_builder.js +147 -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 +41 -32
  20. package/dest/mocks/test_context.d.ts.map +1 -1
  21. package/dest/mocks/test_context.js +138 -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 +36 -33
  36. package/dest/orchestrator/orchestrator.d.ts.map +1 -1
  37. package/dest/orchestrator/orchestrator.js +379 -250
  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/tx-proving-state.d.ts +13 -11
  41. package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
  42. package/dest/orchestrator/tx-proving-state.js +23 -40
  43. package/dest/prover-client/factory.d.ts +1 -1
  44. package/dest/prover-client/index.d.ts +1 -1
  45. package/dest/prover-client/prover-client.d.ts +4 -4
  46. package/dest/prover-client/prover-client.d.ts.map +1 -1
  47. package/dest/prover-client/prover-client.js +5 -4
  48. package/dest/prover-client/server-epoch-prover.d.ts +16 -12
  49. package/dest/prover-client/server-epoch-prover.d.ts.map +1 -1
  50. package/dest/prover-client/server-epoch-prover.js +11 -11
  51. package/dest/proving_broker/broker_prover_facade.d.ts +23 -16
  52. package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
  53. package/dest/proving_broker/broker_prover_facade.js +59 -40
  54. package/dest/proving_broker/config.d.ts +19 -10
  55. package/dest/proving_broker/config.d.ts.map +1 -1
  56. package/dest/proving_broker/config.js +23 -6
  57. package/dest/proving_broker/factory.d.ts +2 -2
  58. package/dest/proving_broker/factory.d.ts.map +1 -1
  59. package/dest/proving_broker/factory.js +5 -1
  60. package/dest/proving_broker/fixtures.d.ts +3 -2
  61. package/dest/proving_broker/fixtures.d.ts.map +1 -1
  62. package/dest/proving_broker/fixtures.js +3 -2
  63. package/dest/proving_broker/index.d.ts +1 -1
  64. package/dest/proving_broker/proof_store/factory.d.ts +2 -2
  65. package/dest/proving_broker/proof_store/factory.js +1 -1
  66. package/dest/proving_broker/proof_store/gcs_proof_store.d.ts +1 -1
  67. package/dest/proving_broker/proof_store/gcs_proof_store.d.ts.map +1 -1
  68. package/dest/proving_broker/proof_store/gcs_proof_store.js +1 -0
  69. package/dest/proving_broker/proof_store/index.d.ts +2 -1
  70. package/dest/proving_broker/proof_store/index.d.ts.map +1 -1
  71. package/dest/proving_broker/proof_store/index.js +1 -0
  72. package/dest/proving_broker/proof_store/inline_proof_store.d.ts +1 -1
  73. package/dest/proving_broker/proof_store/inline_proof_store.d.ts.map +1 -1
  74. package/dest/proving_broker/proof_store/proof_store.d.ts +1 -1
  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 +83 -47
  78. package/dest/proving_broker/proving_agent_instrumentation.d.ts +1 -1
  79. package/dest/proving_broker/proving_agent_instrumentation.d.ts.map +1 -1
  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 +39 -23
  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 +3 -2
  87. package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -1
  88. package/dest/proving_broker/proving_broker_database/persisted.js +12 -10
  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_job_controller.d.ts +9 -9
  94. package/dest/proving_broker/proving_job_controller.d.ts.map +1 -1
  95. package/dest/proving_broker/proving_job_controller.js +87 -60
  96. package/dest/proving_broker/rpc.d.ts +4 -6
  97. package/dest/proving_broker/rpc.d.ts.map +1 -1
  98. package/dest/proving_broker/rpc.js +1 -4
  99. package/dest/test/mock_proof_store.d.ts +9 -0
  100. package/dest/test/mock_proof_store.d.ts.map +1 -0
  101. package/dest/test/mock_proof_store.js +10 -0
  102. package/dest/test/mock_prover.d.ts +23 -17
  103. package/dest/test/mock_prover.d.ts.map +1 -1
  104. package/dest/test/mock_prover.js +37 -19
  105. package/package.json +34 -31
  106. package/src/block-factory/index.ts +1 -0
  107. package/src/block-factory/light.ts +137 -0
  108. package/src/config.ts +25 -9
  109. package/src/light/index.ts +1 -0
  110. package/src/light/lightweight_checkpoint_builder.ts +198 -0
  111. package/src/mocks/fixtures.ts +44 -39
  112. package/src/mocks/test_context.ts +213 -116
  113. package/src/orchestrator/block-building-helpers.ts +258 -334
  114. package/src/orchestrator/block-proving-state.ts +325 -231
  115. package/src/orchestrator/checkpoint-proving-state.ts +303 -0
  116. package/src/orchestrator/epoch-proving-state.ts +191 -113
  117. package/src/orchestrator/orchestrator.ts +582 -314
  118. package/src/orchestrator/tx-proving-state.ts +49 -64
  119. package/src/prover-client/prover-client.ts +16 -14
  120. package/src/prover-client/server-epoch-prover.ts +40 -22
  121. package/src/proving_broker/broker_prover_facade.ts +205 -126
  122. package/src/proving_broker/config.ts +25 -7
  123. package/src/proving_broker/factory.ts +2 -1
  124. package/src/proving_broker/fixtures.ts +8 -3
  125. package/src/proving_broker/proof_store/factory.ts +1 -1
  126. package/src/proving_broker/proof_store/gcs_proof_store.ts +5 -1
  127. package/src/proving_broker/proof_store/index.ts +1 -0
  128. package/src/proving_broker/proof_store/inline_proof_store.ts +1 -1
  129. package/src/proving_broker/proving_agent.ts +89 -47
  130. package/src/proving_broker/proving_broker.ts +56 -33
  131. package/src/proving_broker/proving_broker_database/memory.ts +3 -2
  132. package/src/proving_broker/proving_broker_database/persisted.ts +14 -12
  133. package/src/proving_broker/proving_broker_database.ts +2 -1
  134. package/src/proving_broker/proving_job_controller.ts +92 -81
  135. package/src/proving_broker/rpc.ts +1 -6
  136. package/src/test/mock_proof_store.ts +14 -0
  137. package/src/test/mock_prover.ts +158 -59
  138. package/dest/bin/get-proof-inputs.d.ts +0 -2
  139. package/dest/bin/get-proof-inputs.d.ts.map +0 -1
  140. package/dest/bin/get-proof-inputs.js +0 -51
  141. package/dest/block_builder/index.d.ts +0 -6
  142. package/dest/block_builder/index.d.ts.map +0 -1
  143. package/dest/block_builder/light.d.ts +0 -33
  144. package/dest/block_builder/light.d.ts.map +0 -1
  145. package/dest/block_builder/light.js +0 -82
  146. package/src/bin/get-proof-inputs.ts +0 -59
  147. package/src/block_builder/index.ts +0 -6
  148. package/src/block_builder/light.ts +0 -101
  149. /package/dest/{block_builder → block-factory}/index.js +0 -0
@@ -1,126 +1,159 @@
1
- import { SpongeBlob } from '@aztec/blob-lib';
1
+ import { type BlockBlobData, type BlockEndBlobData, type SpongeBlob, encodeBlockEndBlobData } from '@aztec/blob-lib';
2
2
  import {
3
3
  type ARCHIVE_HEIGHT,
4
- BLOBS_PER_BLOCK,
5
- FIELDS_PER_BLOB,
6
- type L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH,
4
+ type L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
5
+ NESTED_RECURSIVE_PROOF_LENGTH,
7
6
  type NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
8
7
  NUM_BASE_PARITY_PER_ROOT_PARITY,
9
- type RECURSIVE_PROOF_LENGTH,
10
- VK_TREE_HEIGHT,
11
8
  } from '@aztec/constants';
12
- import { padArrayEnd } from '@aztec/foundation/collection';
13
- import { Fr } from '@aztec/foundation/fields';
14
- import type { Logger } from '@aztec/foundation/log';
15
- import type { Tuple } from '@aztec/foundation/serialize';
16
- import { MembershipWitness, type TreeNodeLocation, UnbalancedTreeStore } from '@aztec/foundation/trees';
17
- import { getVKIndex, getVKSiblingPath, getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
18
- import { protocolContractTreeRoot } from '@aztec/protocol-contracts';
19
- import type { L2Block } from '@aztec/stdlib/block';
9
+ import { BlockNumber } from '@aztec/foundation/branded-types';
10
+ import { Fr } from '@aztec/foundation/curves/bn254';
11
+ import { type Tuple, assertLength } from '@aztec/foundation/serialize';
12
+ import { type TreeNodeLocation, UnbalancedTreeStore } from '@aztec/foundation/trees';
20
13
  import type { PublicInputsAndRecursiveProof } from '@aztec/stdlib/interfaces/server';
21
- import { type ParityPublicInputs, RootParityInput, RootParityInputs } from '@aztec/stdlib/parity';
14
+ import { type ParityPublicInputs, ParityRootPrivateInputs } from '@aztec/stdlib/parity';
15
+ import type { RollupHonkProofData } from '@aztec/stdlib/proofs';
22
16
  import {
23
- type BaseOrMergeRollupPublicInputs,
24
- type BlockRootOrBlockMergePublicInputs,
25
- BlockRootRollupBlobData,
26
- BlockRootRollupData,
27
- BlockRootRollupInputs,
28
- ConstantRollupData,
29
- EmptyBlockRootRollupInputs,
30
- MergeRollupInputs,
31
- PreviousRollupData,
32
- SingleTxBlockRootRollupInputs,
17
+ BlockRollupPublicInputs,
18
+ BlockRootEmptyTxFirstRollupPrivateInputs,
19
+ BlockRootFirstRollupPrivateInputs,
20
+ BlockRootRollupPrivateInputs,
21
+ BlockRootSingleTxFirstRollupPrivateInputs,
22
+ BlockRootSingleTxRollupPrivateInputs,
23
+ CheckpointConstantData,
24
+ TxMergeRollupPrivateInputs,
25
+ type TxRollupPublicInputs,
33
26
  } from '@aztec/stdlib/rollup';
34
27
  import type { CircuitName } from '@aztec/stdlib/stats';
35
- import type { AppendOnlyTreeSnapshot, MerkleTreeId } from '@aztec/stdlib/trees';
36
- import { type BlockHeader, type GlobalVariables, StateReference } from '@aztec/stdlib/tx';
28
+ import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
29
+ import { BlockHeader, GlobalVariables, StateReference } from '@aztec/stdlib/tx';
30
+ import type { UInt64 } from '@aztec/stdlib/types';
37
31
 
38
- import { buildBlobHints, buildHeaderFromCircuitOutputs } from './block-building-helpers.js';
39
- import type { EpochProvingState } from './epoch-proving-state.js';
32
+ import { buildHeaderFromCircuitOutputs, toProofData } from './block-building-helpers.js';
33
+ import type { CheckpointProvingState } from './checkpoint-proving-state.js';
40
34
  import type { TxProvingState } from './tx-proving-state.js';
41
35
 
42
- export type TreeSnapshots = Map<MerkleTreeId, AppendOnlyTreeSnapshot>;
36
+ export type ProofState<T, PROOF_LENGTH extends number> = {
37
+ provingOutput?: PublicInputsAndRecursiveProof<T, PROOF_LENGTH>;
38
+ isProving?: boolean;
39
+ };
43
40
 
44
41
  /**
45
42
  * The current state of the proving schedule for a given block. Managed by ProvingState.
46
43
  * Contains the raw inputs and intermediate state to generate every constituent proof in the tree.
47
44
  */
48
45
  export class BlockProvingState {
49
- private baseOrMergeProvingOutputs: UnbalancedTreeStore<
50
- PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
46
+ private baseOrMergeProofs: UnbalancedTreeStore<
47
+ ProofState<TxRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
51
48
  > = new UnbalancedTreeStore(0);
52
- private baseParityProvingOutputs: (PublicInputsAndRecursiveProof<ParityPublicInputs> | undefined)[];
53
- private rootParityProvingOutput: PublicInputsAndRecursiveProof<ParityPublicInputs> | undefined;
54
- private blockRootProvingOutput:
55
- | PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
49
+ private baseParityProofs: (ProofState<ParityPublicInputs, typeof NESTED_RECURSIVE_PROOF_LENGTH> | undefined)[] =
50
+ Array.from({
51
+ length: NUM_BASE_PARITY_PER_ROOT_PARITY,
52
+ }).map(_ => undefined);
53
+ private rootParityProof: ProofState<ParityPublicInputs, typeof NESTED_RECURSIVE_PROOF_LENGTH> | undefined;
54
+ private blockRootProof:
55
+ | ProofState<BlockRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
56
56
  | undefined;
57
- public blockRootRollupStarted: boolean = false;
58
- public block: L2Block | undefined;
59
- public spongeBlobState: SpongeBlob | undefined;
60
- public totalNumTxs: number;
57
+ private builtBlockHeader: BlockHeader | undefined;
58
+ private endState: StateReference | undefined;
59
+ private endSpongeBlob: SpongeBlob | undefined;
61
60
  private txs: TxProvingState[] = [];
62
- public error: string | undefined;
61
+ private isFirstBlock: boolean;
62
+ private error: string | undefined;
63
63
 
64
64
  constructor(
65
65
  public readonly index: number,
66
- public readonly globalVariables: GlobalVariables,
67
- public readonly newL1ToL2Messages: Fr[],
68
- private readonly l1ToL2MessageSubtreeSiblingPath: Tuple<Fr, typeof L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH>,
69
- private readonly l1ToL2MessageTreeSnapshotAfterInsertion: AppendOnlyTreeSnapshot,
70
- private readonly lastArchiveSnapshot: AppendOnlyTreeSnapshot,
71
- private readonly newArchiveSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>,
72
- private readonly previousBlockHeader: BlockHeader,
73
- private readonly parentEpoch: EpochProvingState,
66
+ public readonly blockNumber: BlockNumber,
67
+ public readonly totalNumTxs: number,
68
+ private readonly constants: CheckpointConstantData,
69
+ private readonly timestamp: UInt64,
70
+ public readonly lastArchiveTreeSnapshot: AppendOnlyTreeSnapshot,
71
+ private readonly lastArchiveSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>,
72
+ private readonly lastL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot,
73
+ private readonly lastL1ToL2MessageSubtreeRootSiblingPath: Tuple<
74
+ Fr,
75
+ typeof L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH
76
+ >,
77
+ public readonly newL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot,
78
+ private readonly headerOfLastBlockInPreviousCheckpoint: BlockHeader,
79
+ private readonly startSpongeBlob: SpongeBlob,
80
+ public parentCheckpoint: CheckpointProvingState,
74
81
  ) {
75
- this.baseParityProvingOutputs = Array.from({ length: NUM_BASE_PARITY_PER_ROOT_PARITY }).map(_ => undefined);
76
- this.totalNumTxs = 0;
77
- }
82
+ this.isFirstBlock = index === 0;
83
+ if (!totalNumTxs && !this.isFirstBlock) {
84
+ throw new Error(`Cannot create a block with 0 txs, unless it's the first block.`);
85
+ }
78
86
 
79
- public get blockNumber() {
80
- return this.globalVariables.blockNumber.toNumber();
87
+ this.baseOrMergeProofs = new UnbalancedTreeStore(totalNumTxs);
81
88
  }
82
89
 
83
- public startNewBlock(numTxs: number, numBlobFields: number) {
84
- if (this.spongeBlobState) {
85
- throw new Error(`Block ${this.blockNumber} already initalised.`);
86
- }
87
-
88
- this.baseOrMergeProvingOutputs = new UnbalancedTreeStore(numTxs);
89
- // Initialise the sponge which will eventually absorb all tx effects to be added to the blob.
90
- // Like l1 to l2 messages, we need to know beforehand how many effects will be absorbed.
91
- this.spongeBlobState = SpongeBlob.init(numBlobFields);
92
- this.totalNumTxs = numTxs;
90
+ public get epochNumber(): number {
91
+ return this.parentCheckpoint.epochNumber;
93
92
  }
94
93
 
95
94
  // Adds a transaction to the proving state, returns it's index
96
95
  public addNewTx(tx: TxProvingState) {
97
- if (!this.spongeBlobState) {
98
- throw new Error(`Invalid block proving state, call startNewBlock before adding transactions.`);
96
+ if (!this.isAcceptingTxs()) {
97
+ throw new Error(`Cannot add more txs to block ${this.blockNumber}.`);
99
98
  }
100
-
101
99
  const txIndex = this.txs.length;
102
100
  this.txs[txIndex] = tx;
103
101
  return txIndex;
104
102
  }
105
103
 
104
+ public isAcceptingTxs() {
105
+ return this.txs.length < this.totalNumTxs;
106
+ }
107
+
108
+ public getProcessedTxs() {
109
+ return this.txs.map(t => t.processedTx);
110
+ }
111
+
112
+ public tryStartProvingBase(txIndex: number) {
113
+ if (this.baseOrMergeProofs.getLeaf(txIndex)?.isProving) {
114
+ return false;
115
+ } else {
116
+ this.baseOrMergeProofs.setLeaf(txIndex, { isProving: true });
117
+ return true;
118
+ }
119
+ }
120
+
106
121
  public setBaseRollupProof(
107
122
  txIndex: number,
108
123
  provingOutput: PublicInputsAndRecursiveProof<
109
- BaseOrMergeRollupPublicInputs,
124
+ TxRollupPublicInputs,
110
125
  typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
111
126
  >,
112
127
  ): TreeNodeLocation {
113
- return this.baseOrMergeProvingOutputs.setLeaf(txIndex, provingOutput);
128
+ return this.baseOrMergeProofs.setLeaf(txIndex, { provingOutput });
129
+ }
130
+
131
+ public tryStartProvingMerge(location: TreeNodeLocation) {
132
+ if (this.baseOrMergeProofs.getNode(location)?.isProving) {
133
+ return false;
134
+ } else {
135
+ this.baseOrMergeProofs.setNode(location, { isProving: true });
136
+ return true;
137
+ }
114
138
  }
115
139
 
116
140
  public setMergeRollupProof(
117
141
  location: TreeNodeLocation,
118
142
  provingOutput: PublicInputsAndRecursiveProof<
119
- BaseOrMergeRollupPublicInputs,
143
+ TxRollupPublicInputs,
120
144
  typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
121
145
  >,
122
146
  ) {
123
- this.baseOrMergeProvingOutputs.setNode(location, provingOutput);
147
+ this.baseOrMergeProofs.setNode(location, { provingOutput });
148
+ }
149
+
150
+ public tryStartProvingBaseParity(index: number) {
151
+ if (this.baseParityProofs[index]?.isProving) {
152
+ return false;
153
+ } else {
154
+ this.baseParityProofs[index] = { isProving: true };
155
+ return true;
156
+ }
124
157
  }
125
158
 
126
159
  // Stores a set of root parity inputs at the given index
@@ -130,136 +163,228 @@ export class BlockProvingState {
130
163
  `Unable to set a base parity proofs at index ${index}. Expected at most ${NUM_BASE_PARITY_PER_ROOT_PARITY} proofs.`,
131
164
  );
132
165
  }
133
- this.baseParityProvingOutputs[index] = provingOutput;
166
+ this.baseParityProofs[index] = { provingOutput };
167
+ }
168
+
169
+ public tryStartProvingRootParity() {
170
+ if (this.rootParityProof?.isProving) {
171
+ return false;
172
+ } else {
173
+ this.rootParityProof = { isProving: true };
174
+ return true;
175
+ }
134
176
  }
135
177
 
136
178
  public setRootParityProof(provingOutput: PublicInputsAndRecursiveProof<ParityPublicInputs>) {
137
- this.rootParityProvingOutput = provingOutput;
179
+ this.rootParityProof = { provingOutput };
180
+ }
181
+
182
+ public tryStartProvingBlockRoot() {
183
+ if (this.blockRootProof?.isProving) {
184
+ return false;
185
+ } else {
186
+ this.blockRootProof = { isProving: true };
187
+ return true;
188
+ }
138
189
  }
139
190
 
140
191
  public setBlockRootRollupProof(
141
192
  provingOutput: PublicInputsAndRecursiveProof<
142
- BlockRootOrBlockMergePublicInputs,
193
+ BlockRollupPublicInputs,
143
194
  typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
144
195
  >,
145
- ) {
146
- this.blockRootProvingOutput = provingOutput;
196
+ ): TreeNodeLocation {
197
+ this.blockRootProof = { provingOutput };
198
+ return this.parentCheckpoint.setBlockRootRollupProof(this.index, provingOutput);
147
199
  }
148
200
 
149
- // Returns the complete set of transaction proving state objects
150
- public get allTxs() {
151
- return this.txs;
201
+ public getBlockRootRollupOutput() {
202
+ return this.blockRootProof?.provingOutput?.inputs;
152
203
  }
153
204
 
154
- /** Returns the block number as an epoch number. Used for prioritizing proof requests. */
155
- public get epochNumber(): number {
156
- return this.parentEpoch.epochNumber;
205
+ public async buildBlockHeader() {
206
+ if (this.isAcceptingTxs()) {
207
+ throw new Error('All txs must be added to the block before building the header.');
208
+ }
209
+ if (!this.endState) {
210
+ throw new Error('Call `setEndState` first.');
211
+ }
212
+ if (!this.endSpongeBlob) {
213
+ throw new Error('Call `setEndSpongeBlob` first.');
214
+ }
215
+
216
+ const endSpongeBlob = this.endSpongeBlob.clone();
217
+ const endSpongeBlobHash = await endSpongeBlob.squeeze();
218
+
219
+ this.builtBlockHeader = new BlockHeader(
220
+ this.lastArchiveTreeSnapshot,
221
+ this.endState,
222
+ endSpongeBlobHash,
223
+ this.#getGlobalVariables(),
224
+ this.#getTotalFees(),
225
+ new Fr(this.#getTotalManaUsed()),
226
+ );
227
+
228
+ return this.builtBlockHeader;
229
+ }
230
+
231
+ public getBuiltBlockHeader() {
232
+ return this.builtBlockHeader;
233
+ }
234
+
235
+ public getStartSpongeBlob() {
236
+ return this.startSpongeBlob;
237
+ }
238
+
239
+ public setEndSpongeBlob(endSpongeBlob: SpongeBlob) {
240
+ this.endSpongeBlob = endSpongeBlob;
241
+ }
242
+
243
+ public getEndSpongeBlob() {
244
+ return this.endSpongeBlob;
245
+ }
246
+
247
+ public setEndState(endState: StateReference) {
248
+ this.endState = endState;
249
+ }
250
+
251
+ public hasEndState() {
252
+ return !!this.endState;
253
+ }
254
+
255
+ public getBlockEndBlobFields(): Fr[] {
256
+ return encodeBlockEndBlobData(this.getBlockEndBlobData());
257
+ }
258
+
259
+ getBlockEndBlobData(): BlockEndBlobData {
260
+ if (!this.endState) {
261
+ throw new Error('Call `setEndState` first.');
262
+ }
263
+
264
+ const partial = this.endState.partial;
265
+ return {
266
+ blockEndMarker: {
267
+ numTxs: this.totalNumTxs,
268
+ timestamp: this.timestamp,
269
+ blockNumber: this.blockNumber,
270
+ },
271
+ blockEndStateField: {
272
+ l1ToL2MessageNextAvailableLeafIndex: this.newL1ToL2MessageTreeSnapshot.nextAvailableLeafIndex,
273
+ noteHashNextAvailableLeafIndex: partial.noteHashTree.nextAvailableLeafIndex,
274
+ nullifierNextAvailableLeafIndex: partial.nullifierTree.nextAvailableLeafIndex,
275
+ publicDataNextAvailableLeafIndex: partial.publicDataTree.nextAvailableLeafIndex,
276
+ totalManaUsed: this.#getTotalManaUsed(),
277
+ },
278
+ lastArchiveRoot: this.lastArchiveTreeSnapshot.root,
279
+ noteHashRoot: partial.noteHashTree.root,
280
+ nullifierRoot: partial.nullifierTree.root,
281
+ publicDataRoot: partial.publicDataTree.root,
282
+ l1ToL2MessageRoot: this.isFirstBlock ? this.newL1ToL2MessageTreeSnapshot.root : undefined,
283
+ };
284
+ }
285
+
286
+ public getBlockBlobData(): BlockBlobData {
287
+ return {
288
+ ...this.getBlockEndBlobData(),
289
+ txs: this.getTxEffects().map(t => t.toTxBlobData()),
290
+ };
291
+ }
292
+
293
+ public getTxEffects() {
294
+ return this.txs.map(t => t.processedTx.txEffect);
157
295
  }
158
296
 
159
297
  public getParentLocation(location: TreeNodeLocation) {
160
- return this.baseOrMergeProvingOutputs.getParentLocation(location);
298
+ return this.baseOrMergeProofs.getParentLocation(location);
161
299
  }
162
300
 
163
301
  public getMergeRollupInputs(mergeLocation: TreeNodeLocation) {
164
- const [left, right] = this.baseOrMergeProvingOutputs.getChildren(mergeLocation);
302
+ const [left, right] = this.baseOrMergeProofs.getChildren(mergeLocation).map(c => c?.provingOutput);
165
303
  if (!left || !right) {
166
- throw new Error('At lease one child is not ready.');
304
+ throw new Error('At least one child is not ready for the merge rollup.');
167
305
  }
168
306
 
169
- return new MergeRollupInputs([this.#getPreviousRollupData(left), this.#getPreviousRollupData(right)]);
307
+ return new TxMergeRollupPrivateInputs([toProofData(left), toProofData(right)]);
170
308
  }
171
309
 
172
- public async getBlockRootRollupTypeAndInputs(proverId: Fr) {
173
- if (!this.rootParityProvingOutput) {
174
- throw new Error('Root parity is not ready.');
175
- }
176
-
177
- const proofs = this.#getChildProofsForBlockRoot();
178
- const nonEmptyProofs = proofs.filter(p => !!p);
179
- if (proofs.length !== nonEmptyProofs.length) {
180
- throw new Error('At lease one child is not ready for the block root.');
310
+ public getBlockRootRollupTypeAndInputs() {
311
+ const provingOutputs = this.#getChildProvingOutputsForBlockRoot();
312
+ if (!provingOutputs.every(p => !!p)) {
313
+ throw new Error('At least one child is not ready for the block root rollup.');
181
314
  }
182
315
 
183
- const data = this.#getBlockRootRollupData(proverId);
316
+ const previousRollups = provingOutputs.map(p => toProofData(p));
184
317
 
185
- if (this.totalNumTxs === 0) {
186
- const constants = ConstantRollupData.from({
187
- lastArchive: this.lastArchiveSnapshot,
188
- globalVariables: this.globalVariables,
189
- vkTreeRoot: getVKTreeRoot(),
190
- protocolContractTreeRoot,
191
- });
192
-
193
- return {
194
- rollupType: 'empty-block-root-rollup' satisfies CircuitName,
195
- inputs: EmptyBlockRootRollupInputs.from({
196
- data,
197
- constants,
198
- isPadding: false,
199
- }),
200
- };
318
+ if (this.isFirstBlock) {
319
+ return this.#getFirstBlockRootRollupTypeAndInputs(previousRollups);
201
320
  }
202
321
 
203
- const previousRollupData = await Promise.all(nonEmptyProofs.map(p => this.#getPreviousRollupData(p!)));
204
- const blobData = await this.#getBlockRootRollupBlobData();
205
-
206
- if (previousRollupData.length === 1) {
322
+ const [leftRollup, rightRollup] = previousRollups;
323
+ if (!rightRollup) {
207
324
  return {
208
- rollupType: 'single-tx-block-root-rollup' satisfies CircuitName,
209
- inputs: new SingleTxBlockRootRollupInputs(previousRollupData as [PreviousRollupData], data, blobData),
325
+ rollupType: 'rollup-block-root-single-tx' satisfies CircuitName,
326
+ inputs: new BlockRootSingleTxRollupPrivateInputs(leftRollup, this.lastArchiveSiblingPath),
210
327
  };
211
328
  } else {
212
329
  return {
213
- rollupType: 'block-root-rollup' satisfies CircuitName,
214
- inputs: new BlockRootRollupInputs(
215
- previousRollupData as [PreviousRollupData, PreviousRollupData],
216
- data,
217
- blobData,
218
- ),
330
+ rollupType: 'rollup-block-root' satisfies CircuitName,
331
+ inputs: new BlockRootRollupPrivateInputs([leftRollup, rightRollup], this.lastArchiveSiblingPath),
219
332
  };
220
333
  }
221
334
  }
222
335
 
223
- public async getPaddingBlockRootInputs(proverId: Fr) {
224
- if (!this.rootParityProvingOutput) {
336
+ #getFirstBlockRootRollupTypeAndInputs([leftRollup, rightRollup]: RollupHonkProofData<TxRollupPublicInputs>[]) {
337
+ if (!this.rootParityProof?.provingOutput) {
225
338
  throw new Error('Root parity is not ready.');
226
339
  }
340
+ const l1ToL2Roots = toProofData(this.rootParityProof.provingOutput);
227
341
 
228
- // Use the new block header and archive of the current block as the previous header and archiver of the next padding block.
229
- const newBlockHeader = await this.buildHeaderFromProvingOutputs();
230
- const newArchive = this.blockRootProvingOutput!.inputs.newArchive;
231
-
232
- const data = BlockRootRollupData.from({
233
- l1ToL2Roots: this.#getRootParityData(this.rootParityProvingOutput!),
234
- l1ToL2MessageSubtreeSiblingPath: this.l1ToL2MessageSubtreeSiblingPath,
235
- newArchiveSiblingPath: this.newArchiveSiblingPath,
236
- previousBlockHeader: newBlockHeader,
237
- proverId,
238
- });
239
-
240
- const constants = ConstantRollupData.from({
241
- lastArchive: newArchive,
242
- globalVariables: this.globalVariables,
243
- vkTreeRoot: getVKTreeRoot(),
244
- protocolContractTreeRoot,
245
- });
246
-
247
- return EmptyBlockRootRollupInputs.from({
248
- data,
249
- constants,
250
- isPadding: true,
251
- });
342
+ if (!leftRollup) {
343
+ return {
344
+ rollupType: 'rollup-block-root-first-empty-tx' satisfies CircuitName,
345
+ inputs: new BlockRootEmptyTxFirstRollupPrivateInputs(
346
+ l1ToL2Roots,
347
+ this.lastArchiveTreeSnapshot,
348
+ this.headerOfLastBlockInPreviousCheckpoint.state,
349
+ this.constants,
350
+ this.timestamp,
351
+ this.lastL1ToL2MessageSubtreeRootSiblingPath,
352
+ this.lastArchiveSiblingPath,
353
+ ),
354
+ };
355
+ } else if (!rightRollup) {
356
+ return {
357
+ rollupType: 'rollup-block-root-first-single-tx' satisfies CircuitName,
358
+ inputs: new BlockRootSingleTxFirstRollupPrivateInputs(
359
+ l1ToL2Roots,
360
+ leftRollup,
361
+ this.lastL1ToL2MessageTreeSnapshot,
362
+ this.lastL1ToL2MessageSubtreeRootSiblingPath,
363
+ this.lastArchiveSiblingPath,
364
+ ),
365
+ };
366
+ } else {
367
+ return {
368
+ rollupType: 'rollup-block-root-first' satisfies CircuitName,
369
+ inputs: new BlockRootFirstRollupPrivateInputs(
370
+ l1ToL2Roots,
371
+ [leftRollup, rightRollup],
372
+ this.lastL1ToL2MessageTreeSnapshot,
373
+ this.lastL1ToL2MessageSubtreeRootSiblingPath,
374
+ this.lastArchiveSiblingPath,
375
+ ),
376
+ };
377
+ }
252
378
  }
253
379
 
254
- public getRootParityInputs() {
255
- if (!this.baseParityProvingOutputs.every(p => !!p)) {
380
+ public getParityRootInputs() {
381
+ const baseParityProvingOutputs = this.baseParityProofs.filter(p => !!p?.provingOutput).map(p => p!.provingOutput!);
382
+ if (baseParityProvingOutputs.length !== this.baseParityProofs.length) {
256
383
  throw new Error('At lease one base parity is not ready.');
257
384
  }
258
385
 
259
- const children = this.baseParityProvingOutputs.map(p => this.#getRootParityData(p!));
260
- return new RootParityInputs(
261
- children as Tuple<RootParityInput<typeof RECURSIVE_PROOF_LENGTH>, typeof NUM_BASE_PARITY_PER_ROOT_PARITY>,
262
- );
386
+ const children = baseParityProvingOutputs.map(p => toProofData(p));
387
+ return new ParityRootPrivateInputs(assertLength(children, NUM_BASE_PARITY_PER_ROOT_PARITY));
263
388
  }
264
389
 
265
390
  // Returns a specific transaction proving state
@@ -267,82 +392,47 @@ export class BlockProvingState {
267
392
  return this.txs[txIndex];
268
393
  }
269
394
 
270
- public async buildHeaderFromProvingOutputs(logger?: Logger) {
271
- const previousRollupData =
272
- this.totalNumTxs === 0
273
- ? []
274
- : await Promise.all(this.#getChildProofsForBlockRoot().map(p => this.#getPreviousRollupData(p!)));
275
-
276
- let endPartialState = this.previousBlockHeader.state.partial;
277
- if (this.totalNumTxs !== 0) {
278
- const previousRollupData = this.#getChildProofsForBlockRoot();
279
- const lastRollup = previousRollupData[previousRollupData.length - 1];
280
- if (!lastRollup) {
281
- throw new Error('End state of the block is not available. Last rollup is not ready yet.');
282
- }
283
- endPartialState = lastRollup.inputs.end;
395
+ public async buildHeaderFromProvingOutputs() {
396
+ if (!this.blockRootProof?.provingOutput) {
397
+ throw new Error('Block root rollup is not ready.');
284
398
  }
285
- const endState = new StateReference(this.l1ToL2MessageTreeSnapshotAfterInsertion, endPartialState);
286
-
287
- return buildHeaderFromCircuitOutputs(
288
- previousRollupData.map(d => d.baseOrMergeRollupPublicInputs),
289
- this.rootParityProvingOutput!.inputs,
290
- this.blockRootProvingOutput!.inputs,
291
- endState,
292
- logger,
293
- );
399
+
400
+ return await buildHeaderFromCircuitOutputs(this.blockRootProof.provingOutput.inputs);
294
401
  }
295
402
 
296
403
  public isReadyForMergeRollup(location: TreeNodeLocation) {
297
- return this.baseOrMergeProvingOutputs.getSibling(location) !== undefined;
404
+ return !!this.baseOrMergeProofs.getSibling(location)?.provingOutput;
298
405
  }
299
406
 
300
407
  // Returns true if we have sufficient inputs to execute the block root rollup
301
408
  public isReadyForBlockRootRollup() {
302
- const childProofs = this.#getChildProofsForBlockRoot();
303
- return this.block !== undefined && this.rootParityProvingOutput !== undefined && childProofs.every(p => !!p);
409
+ const childProofs = this.#getChildProvingOutputsForBlockRoot();
410
+ return (!this.isFirstBlock || !!this.rootParityProof?.provingOutput) && childProofs.every(p => !!p);
304
411
  }
305
412
 
306
413
  // Returns true if we have sufficient root parity inputs to execute the root parity circuit
307
414
  public isReadyForRootParity() {
308
- return this.baseParityProvingOutputs.every(p => !!p);
415
+ return this.baseParityProofs.every(p => !!p?.provingOutput);
309
416
  }
310
417
 
311
418
  public isComplete() {
312
- return !!this.blockRootProvingOutput;
419
+ return !!this.blockRootProof;
313
420
  }
314
421
 
315
- // Returns whether the proving state is still valid
316
422
  public verifyState() {
317
- return this.parentEpoch.verifyState();
423
+ return this.parentCheckpoint.verifyState();
318
424
  }
319
425
 
320
- public reject(reason: string) {
321
- this.error = reason;
322
- this.parentEpoch.reject(reason);
426
+ public getError() {
427
+ return this.error;
323
428
  }
324
429
 
325
- #getBlockRootRollupData(proverId: Fr) {
326
- return BlockRootRollupData.from({
327
- l1ToL2Roots: this.#getRootParityData(this.rootParityProvingOutput!),
328
- l1ToL2MessageSubtreeSiblingPath: this.l1ToL2MessageSubtreeSiblingPath,
329
- newArchiveSiblingPath: this.newArchiveSiblingPath,
330
- previousBlockHeader: this.previousBlockHeader,
331
- proverId,
332
- });
333
- }
334
-
335
- async #getBlockRootRollupBlobData() {
336
- const txEffects = this.txs.map(txProvingState => txProvingState.processedTx.txEffect);
337
- const { blobFields, blobCommitments, blobsHash } = await buildBlobHints(txEffects);
338
- return BlockRootRollupBlobData.from({
339
- blobFields: padArrayEnd(blobFields, Fr.ZERO, FIELDS_PER_BLOB * BLOBS_PER_BLOCK),
340
- blobCommitments: padArrayEnd(blobCommitments, [Fr.ZERO, Fr.ZERO], BLOBS_PER_BLOCK),
341
- blobsHash,
342
- });
430
+ public reject(reason: string) {
431
+ this.error = reason;
432
+ this.parentCheckpoint.reject(reason);
343
433
  }
344
434
 
345
- #getChildProofsForBlockRoot() {
435
+ #getChildProvingOutputsForBlockRoot() {
346
436
  if (this.totalNumTxs === 0) {
347
437
  return [];
348
438
  }
@@ -350,30 +440,34 @@ export class BlockProvingState {
350
440
  const rootLocation = { level: 0, index: 0 };
351
441
  // If there's only 1 tx, its base rollup proof will be stored at the root.
352
442
  return this.totalNumTxs === 1
353
- ? [this.baseOrMergeProvingOutputs.getNode(rootLocation)]
354
- : this.baseOrMergeProvingOutputs.getChildren(rootLocation);
355
- }
356
-
357
- #getPreviousRollupData({
358
- inputs,
359
- proof,
360
- verificationKey,
361
- }: PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>) {
362
- const leafIndex = getVKIndex(verificationKey.keyAsFields);
363
- return new PreviousRollupData(
364
- inputs,
365
- proof,
366
- verificationKey.keyAsFields,
367
- new MembershipWitness(VK_TREE_HEIGHT, BigInt(leafIndex), getVKSiblingPath(leafIndex)),
368
- );
443
+ ? [this.baseOrMergeProofs.getNode(rootLocation)?.provingOutput]
444
+ : this.baseOrMergeProofs.getChildren(rootLocation).map(c => c?.provingOutput);
369
445
  }
370
446
 
371
- #getRootParityData({ inputs, proof, verificationKey }: PublicInputsAndRecursiveProof<ParityPublicInputs>) {
372
- return new RootParityInput(
373
- proof,
374
- verificationKey.keyAsFields,
375
- getVKSiblingPath(getVKIndex(verificationKey)),
376
- inputs,
377
- );
447
+ #getGlobalVariables() {
448
+ if (this.txs.length) {
449
+ return this.txs[0].processedTx.globalVariables;
450
+ }
451
+
452
+ const constants = this.constants;
453
+
454
+ return GlobalVariables.from({
455
+ chainId: constants.chainId,
456
+ version: constants.version,
457
+ blockNumber: this.blockNumber,
458
+ slotNumber: constants.slotNumber,
459
+ timestamp: this.timestamp,
460
+ coinbase: constants.coinbase,
461
+ feeRecipient: constants.feeRecipient,
462
+ gasFees: constants.gasFees,
463
+ });
464
+ }
465
+
466
+ #getTotalFees() {
467
+ return this.txs.reduce((acc, tx) => acc.add(tx.processedTx.txEffect.transactionFee), Fr.ZERO);
468
+ }
469
+
470
+ #getTotalManaUsed() {
471
+ return this.txs.reduce((acc, tx) => acc + BigInt(tx.processedTx.gasUsed.billedGas.l2Gas), 0n);
378
472
  }
379
473
  }