@aztec/prover-client 0.0.1-commit.b655e406 → 0.0.1-commit.b6e433891
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.
- package/dest/config.d.ts +2 -2
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +1 -1
- package/dest/index.d.ts +1 -1
- package/dest/light/index.d.ts +2 -0
- package/dest/light/index.d.ts.map +1 -0
- package/dest/light/index.js +1 -0
- package/dest/light/lightweight_checkpoint_builder.d.ts +52 -0
- package/dest/light/lightweight_checkpoint_builder.d.ts.map +1 -0
- package/dest/light/lightweight_checkpoint_builder.js +223 -0
- package/dest/mocks/fixtures.d.ts +1 -4
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +9 -18
- package/dest/mocks/test_context.d.ts +29 -46
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +120 -117
- package/dest/orchestrator/block-building-helpers.d.ts +18 -20
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +90 -115
- package/dest/orchestrator/block-proving-state.d.ts +20 -11
- package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/block-proving-state.js +87 -19
- package/dest/orchestrator/checkpoint-proving-state.d.ts +22 -9
- package/dest/orchestrator/checkpoint-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/checkpoint-proving-state.js +52 -20
- package/dest/orchestrator/epoch-proving-state.d.ts +12 -10
- package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/epoch-proving-state.js +40 -4
- package/dest/orchestrator/index.d.ts +1 -1
- package/dest/orchestrator/orchestrator.d.ts +28 -11
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +582 -180
- package/dest/orchestrator/orchestrator_metrics.d.ts +1 -3
- package/dest/orchestrator/orchestrator_metrics.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator_metrics.js +2 -15
- package/dest/orchestrator/tx-proving-state.d.ts +6 -5
- package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/tx-proving-state.js +7 -16
- package/dest/prover-client/factory.d.ts +3 -3
- package/dest/prover-client/factory.d.ts.map +1 -1
- package/dest/prover-client/index.d.ts +1 -1
- package/dest/prover-client/prover-client.d.ts +6 -6
- package/dest/prover-client/prover-client.d.ts.map +1 -1
- package/dest/prover-client/prover-client.js +15 -10
- package/dest/prover-client/server-epoch-prover.d.ts +8 -7
- package/dest/prover-client/server-epoch-prover.d.ts.map +1 -1
- package/dest/prover-client/server-epoch-prover.js +2 -2
- package/dest/proving_broker/broker_prover_facade.d.ts +25 -23
- package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
- package/dest/proving_broker/broker_prover_facade.js +11 -17
- package/dest/proving_broker/config.d.ts +25 -9
- package/dest/proving_broker/config.d.ts.map +1 -1
- package/dest/proving_broker/config.js +27 -4
- package/dest/proving_broker/factory.d.ts +1 -1
- package/dest/proving_broker/fixtures.d.ts +3 -2
- package/dest/proving_broker/fixtures.d.ts.map +1 -1
- package/dest/proving_broker/fixtures.js +3 -2
- package/dest/proving_broker/index.d.ts +1 -1
- package/dest/proving_broker/proof_store/factory.d.ts +2 -5
- package/dest/proving_broker/proof_store/factory.d.ts.map +1 -1
- package/dest/proving_broker/proof_store/factory.js +7 -30
- package/dest/proving_broker/proof_store/file_store_proof_store.d.ts +18 -0
- package/dest/proving_broker/proof_store/file_store_proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/file_store_proof_store.js +60 -0
- package/dest/proving_broker/proof_store/index.d.ts +2 -2
- package/dest/proving_broker/proof_store/index.d.ts.map +1 -1
- package/dest/proving_broker/proof_store/index.js +1 -1
- package/dest/proving_broker/proof_store/inline_proof_store.d.ts +1 -1
- package/dest/proving_broker/proof_store/inline_proof_store.d.ts.map +1 -1
- package/dest/proving_broker/proof_store/proof_store.d.ts +1 -1
- package/dest/proving_broker/proving_agent.d.ts +5 -9
- package/dest/proving_broker/proving_agent.d.ts.map +1 -1
- package/dest/proving_broker/proving_agent.js +4 -19
- package/dest/proving_broker/proving_broker.d.ts +7 -4
- package/dest/proving_broker/proving_broker.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker.js +42 -15
- package/dest/proving_broker/proving_broker_database/memory.d.ts +3 -2
- package/dest/proving_broker/proving_broker_database/memory.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker_database/persisted.d.ts +5 -3
- package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker_database/persisted.js +392 -3
- package/dest/proving_broker/proving_broker_database.d.ts +3 -2
- package/dest/proving_broker/proving_broker_database.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker_instrumentation.d.ts +3 -1
- package/dest/proving_broker/proving_broker_instrumentation.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker_instrumentation.js +22 -35
- package/dest/proving_broker/proving_job_controller.d.ts +5 -3
- package/dest/proving_broker/proving_job_controller.d.ts.map +1 -1
- package/dest/proving_broker/proving_job_controller.js +8 -6
- package/dest/proving_broker/rpc.d.ts +7 -5
- package/dest/proving_broker/rpc.d.ts.map +1 -1
- package/dest/proving_broker/rpc.js +8 -0
- package/dest/test/mock_proof_store.d.ts +1 -1
- package/dest/test/mock_proof_store.d.ts.map +1 -1
- package/dest/test/mock_prover.d.ts +5 -6
- package/dest/test/mock_prover.d.ts.map +1 -1
- package/dest/test/mock_prover.js +4 -4
- package/package.json +22 -21
- package/src/config.ts +1 -1
- package/src/light/index.ts +1 -0
- package/src/light/lightweight_checkpoint_builder.ts +312 -0
- package/src/mocks/fixtures.ts +9 -31
- package/src/mocks/test_context.ts +159 -178
- package/src/orchestrator/block-building-helpers.ts +129 -209
- package/src/orchestrator/block-proving-state.ts +109 -22
- package/src/orchestrator/checkpoint-proving-state.ts +75 -25
- package/src/orchestrator/epoch-proving-state.ts +67 -15
- package/src/orchestrator/orchestrator.ts +191 -173
- package/src/orchestrator/orchestrator_metrics.ts +2 -25
- package/src/orchestrator/tx-proving-state.ts +10 -27
- package/src/prover-client/factory.ts +6 -2
- package/src/prover-client/prover-client.ts +33 -24
- package/src/prover-client/server-epoch-prover.ts +6 -7
- package/src/proving_broker/broker_prover_facade.ts +38 -39
- package/src/proving_broker/config.ts +31 -2
- package/src/proving_broker/fixtures.ts +8 -3
- package/src/proving_broker/proof_store/factory.ts +10 -32
- package/src/proving_broker/proof_store/file_store_proof_store.ts +78 -0
- package/src/proving_broker/proof_store/index.ts +1 -1
- package/src/proving_broker/proving_agent.ts +6 -19
- package/src/proving_broker/proving_broker.ts +43 -12
- package/src/proving_broker/proving_broker_database/memory.ts +2 -1
- package/src/proving_broker/proving_broker_database/persisted.ts +20 -5
- package/src/proving_broker/proving_broker_database.ts +2 -1
- package/src/proving_broker/proving_broker_instrumentation.ts +23 -35
- package/src/proving_broker/proving_job_controller.ts +13 -7
- package/src/proving_broker/rpc.ts +14 -0
- package/src/test/mock_prover.ts +2 -14
- package/dest/block-factory/index.d.ts +0 -2
- package/dest/block-factory/index.d.ts.map +0 -1
- package/dest/block-factory/index.js +0 -1
- package/dest/block-factory/light.d.ts +0 -38
- package/dest/block-factory/light.d.ts.map +0 -1
- package/dest/block-factory/light.js +0 -94
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts +0 -14
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts.map +0 -1
- package/dest/proving_broker/proof_store/gcs_proof_store.js +0 -52
- package/dest/proving_broker/proving_agent_instrumentation.d.ts +0 -8
- package/dest/proving_broker/proving_agent_instrumentation.d.ts.map +0 -1
- package/dest/proving_broker/proving_agent_instrumentation.js +0 -16
- package/src/block-factory/index.ts +0 -1
- package/src/block-factory/light.ts +0 -140
- package/src/proving_broker/proof_store/gcs_proof_store.ts +0 -76
- package/src/proving_broker/proving_agent_instrumentation.ts +0 -21
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BatchedBlob, FinalBlobBatchingChallenges, SpongeBlob } from '@aztec/blob-lib';
|
|
1
|
+
import { BatchedBlob, FinalBlobBatchingChallenges, SpongeBlob } from '@aztec/blob-lib/types';
|
|
2
2
|
import {
|
|
3
3
|
L1_TO_L2_MSG_SUBTREE_HEIGHT,
|
|
4
4
|
L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
|
|
@@ -6,22 +6,25 @@ import {
|
|
|
6
6
|
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
7
7
|
NUM_BASE_PARITY_PER_ROOT_PARITY,
|
|
8
8
|
} from '@aztec/constants';
|
|
9
|
+
import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
|
|
9
10
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
11
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
10
12
|
import { AbortError } from '@aztec/foundation/error';
|
|
11
|
-
import {
|
|
12
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
13
|
+
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
13
14
|
import { promiseWithResolvers } from '@aztec/foundation/promise';
|
|
15
|
+
import { SerialQueue } from '@aztec/foundation/queue';
|
|
14
16
|
import { assertLength } from '@aztec/foundation/serialize';
|
|
17
|
+
import { sleep } from '@aztec/foundation/sleep';
|
|
15
18
|
import { pushTestData } from '@aztec/foundation/testing';
|
|
16
19
|
import { elapsed } from '@aztec/foundation/timer';
|
|
17
20
|
import type { TreeNodeLocation } from '@aztec/foundation/trees';
|
|
18
|
-
import {
|
|
19
|
-
import { EthAddress, createBlockEndMarker } from '@aztec/stdlib/block';
|
|
21
|
+
import { EthAddress } from '@aztec/stdlib/block';
|
|
20
22
|
import type {
|
|
21
23
|
EpochProver,
|
|
22
24
|
ForkMerkleTreeOperations,
|
|
23
25
|
MerkleTreeWriteOperations,
|
|
24
26
|
PublicInputsAndRecursiveProof,
|
|
27
|
+
ReadonlyWorldStateAccess,
|
|
25
28
|
ServerCircuitProver,
|
|
26
29
|
} from '@aztec/stdlib/interfaces/server';
|
|
27
30
|
import type { Proof } from '@aztec/stdlib/proofs';
|
|
@@ -54,7 +57,6 @@ import {
|
|
|
54
57
|
import { inspect } from 'util';
|
|
55
58
|
|
|
56
59
|
import {
|
|
57
|
-
buildBlockHeaderFromTxs,
|
|
58
60
|
buildHeaderFromCircuitOutputs,
|
|
59
61
|
getLastSiblingPath,
|
|
60
62
|
getPublicChonkVerifierPrivateInputsFromTx,
|
|
@@ -71,8 +73,6 @@ import { EpochProvingState, type ProvingResult, type TreeSnapshots } from './epo
|
|
|
71
73
|
import { ProvingOrchestratorMetrics } from './orchestrator_metrics.js';
|
|
72
74
|
import { TxProvingState } from './tx-proving-state.js';
|
|
73
75
|
|
|
74
|
-
const logger = createLogger('prover-client:orchestrator');
|
|
75
|
-
|
|
76
76
|
/**
|
|
77
77
|
* Implements an event driven proving scheduler to build the recursive proof tree. The idea being:
|
|
78
78
|
* 1. Transactions are provided to the scheduler post simulation.
|
|
@@ -93,15 +93,23 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
93
93
|
|
|
94
94
|
private provingPromise: Promise<ProvingResult> | undefined = undefined;
|
|
95
95
|
private metrics: ProvingOrchestratorMetrics;
|
|
96
|
-
|
|
96
|
+
// eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
|
|
97
|
+
private dbs: Map<BlockNumber, MerkleTreeWriteOperations> = new Map();
|
|
98
|
+
private logger: Logger;
|
|
99
|
+
private deferredJobQueue = new SerialQueue();
|
|
97
100
|
|
|
98
101
|
constructor(
|
|
99
|
-
private dbProvider: ForkMerkleTreeOperations,
|
|
102
|
+
private dbProvider: ReadonlyWorldStateAccess & ForkMerkleTreeOperations,
|
|
100
103
|
private prover: ServerCircuitProver,
|
|
101
104
|
private readonly proverId: EthAddress,
|
|
105
|
+
private readonly cancelJobsOnStop: boolean = false,
|
|
106
|
+
private readonly enqueueConcurrency: number,
|
|
102
107
|
telemetryClient: TelemetryClient = getTelemetryClient(),
|
|
108
|
+
bindings?: LoggerBindings,
|
|
103
109
|
) {
|
|
110
|
+
this.logger = createLogger('prover-client:orchestrator', bindings);
|
|
104
111
|
this.metrics = new ProvingOrchestratorMetrics(telemetryClient, 'ProvingOrchestrator');
|
|
112
|
+
this.deferredJobQueue.start(this.enqueueConcurrency);
|
|
105
113
|
}
|
|
106
114
|
|
|
107
115
|
get tracer(): Tracer {
|
|
@@ -112,13 +120,19 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
112
120
|
return this.proverId;
|
|
113
121
|
}
|
|
114
122
|
|
|
115
|
-
public
|
|
123
|
+
public getNumActiveForks() {
|
|
124
|
+
return this.dbs.size;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
public async stop(): Promise<void> {
|
|
128
|
+
// Grab the old queue before cancel() replaces it, so we can await its draining.
|
|
129
|
+
const oldQueue = this.deferredJobQueue;
|
|
116
130
|
this.cancel();
|
|
117
|
-
|
|
131
|
+
await oldQueue.cancel();
|
|
118
132
|
}
|
|
119
133
|
|
|
120
134
|
public startNewEpoch(
|
|
121
|
-
epochNumber:
|
|
135
|
+
epochNumber: EpochNumber,
|
|
122
136
|
totalNumCheckpoints: number,
|
|
123
137
|
finalBlobBatchingChallenges: FinalBlobBatchingChallenges,
|
|
124
138
|
) {
|
|
@@ -130,7 +144,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
130
144
|
|
|
131
145
|
const { promise: _promise, resolve, reject } = promiseWithResolvers<ProvingResult>();
|
|
132
146
|
const promise = _promise.catch((reason): ProvingResult => ({ status: 'failure', reason }));
|
|
133
|
-
logger.info(`Starting epoch ${epochNumber} with ${totalNumCheckpoints} checkpoints.`);
|
|
147
|
+
this.logger.info(`Starting epoch ${epochNumber} with ${totalNumCheckpoints} checkpoints.`);
|
|
134
148
|
this.provingState = new EpochProvingState(
|
|
135
149
|
epochNumber,
|
|
136
150
|
totalNumCheckpoints,
|
|
@@ -142,12 +156,19 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
142
156
|
this.provingPromise = promise;
|
|
143
157
|
}
|
|
144
158
|
|
|
159
|
+
/**
|
|
160
|
+
* Starts a new checkpoint.
|
|
161
|
+
* @param checkpointIndex - The index of the checkpoint in the epoch.
|
|
162
|
+
* @param constants - The constants for this checkpoint.
|
|
163
|
+
* @param l1ToL2Messages - The set of L1 to L2 messages to be inserted at the beginning of this checkpoint.
|
|
164
|
+
* @param totalNumBlocks - The total number of blocks expected in the checkpoint (must be at least one).
|
|
165
|
+
* @param headerOfLastBlockInPreviousCheckpoint - The header of the last block in the previous checkpoint.
|
|
166
|
+
*/
|
|
145
167
|
public async startNewCheckpoint(
|
|
146
168
|
checkpointIndex: number,
|
|
147
169
|
constants: CheckpointConstantData,
|
|
148
170
|
l1ToL2Messages: Fr[],
|
|
149
171
|
totalNumBlocks: number,
|
|
150
|
-
totalNumBlobFields: number,
|
|
151
172
|
headerOfLastBlockInPreviousCheckpoint: BlockHeader,
|
|
152
173
|
) {
|
|
153
174
|
if (!this.provingState) {
|
|
@@ -162,7 +183,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
162
183
|
const lastBlockNumber = headerOfLastBlockInPreviousCheckpoint.globalVariables.blockNumber;
|
|
163
184
|
const db = await this.dbProvider.fork(lastBlockNumber);
|
|
164
185
|
|
|
165
|
-
const firstBlockNumber = lastBlockNumber + 1;
|
|
186
|
+
const firstBlockNumber = BlockNumber(lastBlockNumber + 1);
|
|
166
187
|
this.dbs.set(firstBlockNumber, db);
|
|
167
188
|
|
|
168
189
|
// Get archive sibling path before any block in this checkpoint lands.
|
|
@@ -180,7 +201,6 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
180
201
|
checkpointIndex,
|
|
181
202
|
constants,
|
|
182
203
|
totalNumBlocks,
|
|
183
|
-
totalNumBlobFields,
|
|
184
204
|
headerOfLastBlockInPreviousCheckpoint,
|
|
185
205
|
lastArchiveSiblingPath,
|
|
186
206
|
l1ToL2Messages,
|
|
@@ -201,7 +221,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
201
221
|
@trackSpan('ProvingOrchestrator.startNewBlock', blockNumber => ({
|
|
202
222
|
[Attributes.BLOCK_NUMBER]: blockNumber,
|
|
203
223
|
}))
|
|
204
|
-
public async startNewBlock(blockNumber:
|
|
224
|
+
public async startNewBlock(blockNumber: BlockNumber, timestamp: UInt64, totalNumTxs: number) {
|
|
205
225
|
if (!this.provingState) {
|
|
206
226
|
throw new Error('Empty epoch proving state. Call startNewEpoch before starting a block.');
|
|
207
227
|
}
|
|
@@ -216,21 +236,21 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
216
236
|
}
|
|
217
237
|
|
|
218
238
|
const constants = checkpointProvingState.constants;
|
|
219
|
-
logger.info(`Starting block ${blockNumber} for slot ${constants.slotNumber
|
|
239
|
+
this.logger.info(`Starting block ${blockNumber} for slot ${constants.slotNumber}.`);
|
|
220
240
|
|
|
221
241
|
// Fork the db only when it's not already set. The db for the first block is set in `startNewCheckpoint`.
|
|
222
242
|
if (!this.dbs.has(blockNumber)) {
|
|
223
243
|
// Fork world state at the end of the immediately previous block
|
|
224
|
-
const db = await this.dbProvider.fork(blockNumber - 1);
|
|
244
|
+
const db = await this.dbProvider.fork(BlockNumber(blockNumber - 1));
|
|
225
245
|
this.dbs.set(blockNumber, db);
|
|
226
246
|
}
|
|
227
|
-
const db = this.
|
|
247
|
+
const db = this.getDbForBlock(blockNumber);
|
|
228
248
|
|
|
229
249
|
// Get archive snapshot and sibling path before any txs in this block lands.
|
|
230
250
|
const lastArchiveTreeSnapshot = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
231
251
|
const lastArchiveSiblingPath = await getRootTreeSiblingPath(MerkleTreeId.ARCHIVE, db);
|
|
232
252
|
|
|
233
|
-
const blockProvingState =
|
|
253
|
+
const blockProvingState = checkpointProvingState.startNewBlock(
|
|
234
254
|
blockNumber,
|
|
235
255
|
timestamp,
|
|
236
256
|
totalNumTxs,
|
|
@@ -248,11 +268,16 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
248
268
|
// Because `addTxs` won't be called for a block without txs, and that's where the sponge blob state is computed.
|
|
249
269
|
// We need to set its end sponge blob here, which will become the start sponge blob for the next block.
|
|
250
270
|
if (totalNumTxs === 0) {
|
|
271
|
+
const endState = await db.getStateReference();
|
|
272
|
+
blockProvingState.setEndState(endState);
|
|
273
|
+
|
|
251
274
|
const endSpongeBlob = blockProvingState.getStartSpongeBlob().clone();
|
|
252
|
-
|
|
275
|
+
const blockEndBlobFields = blockProvingState.getBlockEndBlobFields();
|
|
276
|
+
await endSpongeBlob.absorb(blockEndBlobFields);
|
|
253
277
|
blockProvingState.setEndSpongeBlob(endSpongeBlob);
|
|
254
278
|
|
|
255
|
-
//
|
|
279
|
+
// Try to accumulate the out hashes and blobs as far as we can:
|
|
280
|
+
await this.provingState.accumulateCheckpointOutHashes();
|
|
256
281
|
await this.provingState.setBlobAccumulators();
|
|
257
282
|
}
|
|
258
283
|
}
|
|
@@ -272,11 +297,11 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
272
297
|
if (!txs.length) {
|
|
273
298
|
// To avoid an ugly throw below. If we require an empty block, we can just call setBlockCompleted
|
|
274
299
|
// on a block with no txs. We cannot do that here because we cannot find the blockNumber without any txs.
|
|
275
|
-
logger.warn(`Provided no txs to orchestrator addTxs.`);
|
|
300
|
+
this.logger.warn(`Provided no txs to orchestrator addTxs.`);
|
|
276
301
|
return;
|
|
277
302
|
}
|
|
278
303
|
|
|
279
|
-
const blockNumber = txs[0].globalVariables.blockNumber;
|
|
304
|
+
const blockNumber = BlockNumber(txs[0].globalVariables.blockNumber);
|
|
280
305
|
const provingState = this.provingState.getBlockProvingStateByBlockNumber(blockNumber!);
|
|
281
306
|
if (!provingState) {
|
|
282
307
|
throw new Error(`Proving state for block ${blockNumber} not found. Call startNewBlock first.`);
|
|
@@ -292,9 +317,9 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
292
317
|
throw new Error(`Block ${blockNumber} has been initialized with transactions.`);
|
|
293
318
|
}
|
|
294
319
|
|
|
295
|
-
logger.info(`Adding ${txs.length} transactions to block ${blockNumber}`);
|
|
320
|
+
this.logger.info(`Adding ${txs.length} transactions to block ${blockNumber}`);
|
|
296
321
|
|
|
297
|
-
const db = this.
|
|
322
|
+
const db = this.getDbForBlock(blockNumber);
|
|
298
323
|
const lastArchive = provingState.lastArchiveTreeSnapshot;
|
|
299
324
|
const newL1ToL2MessageTreeSnapshot = provingState.newL1ToL2MessageTreeSnapshot;
|
|
300
325
|
const spongeBlobState = provingState.getStartSpongeBlob().clone();
|
|
@@ -307,7 +332,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
307
332
|
|
|
308
333
|
validateTx(tx);
|
|
309
334
|
|
|
310
|
-
logger.
|
|
335
|
+
this.logger.debug(`Received transaction: ${tx.hash}`);
|
|
311
336
|
|
|
312
337
|
const startSpongeBlob = spongeBlobState.clone();
|
|
313
338
|
const [hints, treeSnapshots] = await this.prepareBaseRollupInputs(
|
|
@@ -328,10 +353,10 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
328
353
|
const txIndex = provingState.addNewTx(txProvingState);
|
|
329
354
|
if (txProvingState.requireAvmProof) {
|
|
330
355
|
this.getOrEnqueueChonkVerifier(provingState, txIndex);
|
|
331
|
-
logger.debug(`Enqueueing public VM for tx ${txIndex}`);
|
|
356
|
+
this.logger.debug(`Enqueueing public VM for tx ${txIndex}`);
|
|
332
357
|
this.enqueueVM(provingState, txIndex);
|
|
333
358
|
} else {
|
|
334
|
-
logger.debug(`Enqueueing base rollup for private-only tx ${txIndex}`);
|
|
359
|
+
this.logger.debug(`Enqueueing base rollup for private-only tx ${txIndex}`);
|
|
335
360
|
this.enqueueBaseRollup(provingState, txIndex);
|
|
336
361
|
}
|
|
337
362
|
} catch (err: any) {
|
|
@@ -341,11 +366,16 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
341
366
|
}
|
|
342
367
|
}
|
|
343
368
|
|
|
344
|
-
await
|
|
369
|
+
const endState = await db.getStateReference();
|
|
370
|
+
provingState.setEndState(endState);
|
|
371
|
+
|
|
372
|
+
const blockEndBlobFields = provingState.getBlockEndBlobFields();
|
|
373
|
+
await spongeBlobState.absorb(blockEndBlobFields);
|
|
345
374
|
|
|
346
375
|
provingState.setEndSpongeBlob(spongeBlobState);
|
|
347
376
|
|
|
348
|
-
// Txs have been added to the block. Now try to accumulate the blobs as far as we can:
|
|
377
|
+
// Txs have been added to the block. Now try to accumulate the out hashes and blobs as far as we can:
|
|
378
|
+
await this.provingState.accumulateCheckpointOutHashes();
|
|
349
379
|
await this.provingState.setBlobAccumulators();
|
|
350
380
|
}
|
|
351
381
|
|
|
@@ -369,7 +399,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
369
399
|
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
370
400
|
>
|
|
371
401
|
>();
|
|
372
|
-
logger.debug(`Starting chonk verifier circuit for tx ${txHash}`);
|
|
402
|
+
this.logger.debug(`Starting chonk verifier circuit for tx ${txHash}`);
|
|
373
403
|
this.doEnqueueChonkVerifier(txHash, privateInputs, proof => {
|
|
374
404
|
tubeProof.resolve(proof);
|
|
375
405
|
});
|
|
@@ -382,10 +412,10 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
382
412
|
* Marks the block as completed.
|
|
383
413
|
* Computes the block header and updates the archive tree.
|
|
384
414
|
*/
|
|
385
|
-
@trackSpan('ProvingOrchestrator.setBlockCompleted', (blockNumber:
|
|
415
|
+
@trackSpan('ProvingOrchestrator.setBlockCompleted', (blockNumber: BlockNumber) => ({
|
|
386
416
|
[Attributes.BLOCK_NUMBER]: blockNumber,
|
|
387
417
|
}))
|
|
388
|
-
public async setBlockCompleted(blockNumber:
|
|
418
|
+
public async setBlockCompleted(blockNumber: BlockNumber, expectedHeader?: BlockHeader): Promise<BlockHeader> {
|
|
389
419
|
const provingState = this.provingState?.getBlockProvingStateByBlockNumber(blockNumber);
|
|
390
420
|
if (!provingState) {
|
|
391
421
|
throw new Error(`Block proving state for ${blockNumber} not found`);
|
|
@@ -408,39 +438,31 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
408
438
|
);
|
|
409
439
|
}
|
|
410
440
|
|
|
411
|
-
//
|
|
412
|
-
logger.verbose(`Block ${blockNumber} completed. Assembling header.`);
|
|
413
|
-
const header = await
|
|
414
|
-
|
|
415
|
-
await this.verifyBuiltBlockAgainstSyncedState(provingState);
|
|
416
|
-
|
|
417
|
-
return header;
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
private async buildL2BlockHeader(provingState: BlockProvingState, expectedHeader?: BlockHeader) {
|
|
421
|
-
// Collect all txs in this block to build the header. The function calling this has made sure that all txs have been added.
|
|
422
|
-
const txs = provingState.getProcessedTxs();
|
|
423
|
-
|
|
424
|
-
const startSpongeBlob = provingState.getStartSpongeBlob();
|
|
425
|
-
|
|
426
|
-
// Get db for this block
|
|
427
|
-
const db = this.dbs.get(provingState.blockNumber)!;
|
|
428
|
-
|
|
429
|
-
// Given we've applied every change from this block, now assemble the block header
|
|
430
|
-
// and update the archive tree, so we're ready to start processing the next block
|
|
431
|
-
const header = await buildBlockHeaderFromTxs(txs, provingState.getGlobalVariables(), startSpongeBlob, db);
|
|
441
|
+
// Given we've applied every change from this block, now assemble the block header:
|
|
442
|
+
this.logger.verbose(`Block ${blockNumber} completed. Assembling header.`);
|
|
443
|
+
const header = await provingState.buildBlockHeader();
|
|
432
444
|
|
|
433
445
|
if (expectedHeader && !header.equals(expectedHeader)) {
|
|
434
|
-
logger.error(`Block header mismatch: header=${header} expectedHeader=${expectedHeader}`);
|
|
446
|
+
this.logger.error(`Block header mismatch: header=${header} expectedHeader=${expectedHeader}`);
|
|
435
447
|
throw new Error('Block header mismatch');
|
|
436
448
|
}
|
|
437
449
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
);
|
|
441
|
-
await db.updateArchive(header);
|
|
450
|
+
// Get db for this block and remove from map — no other code should use it after this point.
|
|
451
|
+
const db = this.getDbForBlock(provingState.blockNumber);
|
|
452
|
+
this.dbs.delete(provingState.blockNumber);
|
|
442
453
|
|
|
443
|
-
|
|
454
|
+
// Update the archive tree, capture the snapshot, and close the fork deterministically.
|
|
455
|
+
try {
|
|
456
|
+
this.logger.verbose(
|
|
457
|
+
`Updating archive tree with block ${provingState.blockNumber} header ${(await header.hash()).toString()}`,
|
|
458
|
+
);
|
|
459
|
+
await db.updateArchive(header);
|
|
460
|
+
provingState.setBuiltArchive(await getTreeSnapshot(MerkleTreeId.ARCHIVE, db));
|
|
461
|
+
} finally {
|
|
462
|
+
await db.close();
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
await this.verifyBuiltBlockAgainstSyncedState(provingState);
|
|
444
466
|
|
|
445
467
|
return header;
|
|
446
468
|
}
|
|
@@ -449,31 +471,34 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
449
471
|
protected async verifyBuiltBlockAgainstSyncedState(provingState: BlockProvingState) {
|
|
450
472
|
const builtBlockHeader = provingState.getBuiltBlockHeader();
|
|
451
473
|
if (!builtBlockHeader) {
|
|
452
|
-
logger.debug('Block header not built yet, skipping header check.');
|
|
474
|
+
this.logger.debug('Block header not built yet, skipping header check.');
|
|
453
475
|
return;
|
|
454
476
|
}
|
|
455
477
|
|
|
456
478
|
const output = provingState.getBlockRootRollupOutput();
|
|
457
479
|
if (!output) {
|
|
458
|
-
logger.debug('Block root rollup proof not built yet, skipping header check.');
|
|
480
|
+
this.logger.debug('Block root rollup proof not built yet, skipping header check.');
|
|
459
481
|
return;
|
|
460
482
|
}
|
|
483
|
+
|
|
484
|
+
const newArchive = provingState.getBuiltArchive();
|
|
485
|
+
if (!newArchive) {
|
|
486
|
+
this.logger.debug('Archive snapshot not yet captured, skipping header check.');
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
|
|
461
490
|
const header = await buildHeaderFromCircuitOutputs(output);
|
|
462
491
|
|
|
463
492
|
if (!(await header.hash()).equals(await builtBlockHeader.hash())) {
|
|
464
|
-
logger.error(`Block header mismatch.\nCircuit: ${inspect(header)}\nComputed: ${inspect(builtBlockHeader)}`);
|
|
493
|
+
this.logger.error(`Block header mismatch.\nCircuit: ${inspect(header)}\nComputed: ${inspect(builtBlockHeader)}`);
|
|
465
494
|
provingState.reject(`Block header hash mismatch.`);
|
|
466
495
|
return;
|
|
467
496
|
}
|
|
468
497
|
|
|
469
|
-
// Get db for this block
|
|
470
498
|
const blockNumber = provingState.blockNumber;
|
|
471
|
-
const db = this.dbs.get(blockNumber)!;
|
|
472
|
-
|
|
473
|
-
const newArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
474
499
|
const syncedArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, this.dbProvider.getSnapshot(blockNumber));
|
|
475
500
|
if (!syncedArchive.equals(newArchive)) {
|
|
476
|
-
logger.error(
|
|
501
|
+
this.logger.error(
|
|
477
502
|
`Archive tree mismatch for block ${blockNumber}: world state synced to ${inspect(
|
|
478
503
|
syncedArchive,
|
|
479
504
|
)} but built ${inspect(newArchive)}`,
|
|
@@ -484,32 +509,43 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
484
509
|
|
|
485
510
|
const circuitArchive = output.newArchive;
|
|
486
511
|
if (!newArchive.equals(circuitArchive)) {
|
|
487
|
-
logger.error(`New archive mismatch.\nCircuit: ${output.newArchive}\nComputed: ${newArchive}`);
|
|
512
|
+
this.logger.error(`New archive mismatch.\nCircuit: ${output.newArchive}\nComputed: ${newArchive}`);
|
|
488
513
|
provingState.reject(`New archive mismatch.`);
|
|
489
514
|
return;
|
|
490
515
|
}
|
|
491
|
-
|
|
492
|
-
// TODO(palla/prover): This closes the fork only on the happy path. If this epoch orchestrator
|
|
493
|
-
// is aborted and never reaches this point, it will leak the fork. We need to add a global cleanup,
|
|
494
|
-
// but have to make sure it only runs once all operations are completed, otherwise some function here
|
|
495
|
-
// will attempt to access the fork after it was closed.
|
|
496
|
-
logger.debug(`Cleaning up world state fork for ${blockNumber}`);
|
|
497
|
-
void this.dbs
|
|
498
|
-
.get(blockNumber)
|
|
499
|
-
?.close()
|
|
500
|
-
.then(() => this.dbs.delete(blockNumber))
|
|
501
|
-
.catch(err => logger.error(`Error closing db for block ${blockNumber}`, err));
|
|
502
516
|
}
|
|
503
517
|
|
|
504
518
|
/**
|
|
505
|
-
* Cancel any further proving
|
|
519
|
+
* Cancel any further proving.
|
|
520
|
+
* If cancelJobsOnStop is true, aborts all pending jobs with the broker (which marks them as 'Aborted').
|
|
521
|
+
* If cancelJobsOnStop is false (default), jobs remain in the broker queue and can be reused on restart/reorg.
|
|
506
522
|
*/
|
|
507
523
|
public cancel() {
|
|
508
|
-
|
|
509
|
-
|
|
524
|
+
void this.deferredJobQueue.cancel();
|
|
525
|
+
// Recreate the queue so it can accept jobs for subsequent epochs.
|
|
526
|
+
this.deferredJobQueue = new SerialQueue();
|
|
527
|
+
this.deferredJobQueue.start(this.enqueueConcurrency);
|
|
528
|
+
|
|
529
|
+
if (this.cancelJobsOnStop) {
|
|
530
|
+
for (const controller of this.pendingProvingJobs) {
|
|
531
|
+
controller.abort();
|
|
532
|
+
}
|
|
510
533
|
}
|
|
511
534
|
|
|
512
535
|
this.provingState?.cancel();
|
|
536
|
+
|
|
537
|
+
for (const [blockNumber, db] of this.dbs.entries()) {
|
|
538
|
+
void db.close().catch(err => this.logger.error(`Error closing db for block ${blockNumber}`, err));
|
|
539
|
+
}
|
|
540
|
+
this.dbs.clear();
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
private getDbForBlock(blockNumber: BlockNumber): MerkleTreeWriteOperations {
|
|
544
|
+
const db = this.dbs.get(blockNumber);
|
|
545
|
+
if (!db) {
|
|
546
|
+
throw new Error(`World state fork for block ${blockNumber} not found.`);
|
|
547
|
+
}
|
|
548
|
+
return db;
|
|
513
549
|
}
|
|
514
550
|
|
|
515
551
|
/**
|
|
@@ -553,7 +589,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
553
589
|
callback: (result: T) => void | Promise<void>,
|
|
554
590
|
) {
|
|
555
591
|
if (!provingState.verifyState()) {
|
|
556
|
-
logger.debug(`Not enqueuing job, state no longer valid`);
|
|
592
|
+
this.logger.debug(`Not enqueuing job, state no longer valid`);
|
|
557
593
|
return;
|
|
558
594
|
}
|
|
559
595
|
|
|
@@ -571,7 +607,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
571
607
|
|
|
572
608
|
const result = await request(controller.signal);
|
|
573
609
|
if (!provingState.verifyState()) {
|
|
574
|
-
logger.debug(`State no longer valid, discarding result`);
|
|
610
|
+
this.logger.debug(`State no longer valid, discarding result`);
|
|
575
611
|
return;
|
|
576
612
|
}
|
|
577
613
|
|
|
@@ -589,7 +625,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
589
625
|
return;
|
|
590
626
|
}
|
|
591
627
|
|
|
592
|
-
logger.error(`Error thrown when proving job`, err);
|
|
628
|
+
this.logger.error(`Error thrown when proving job`, err);
|
|
593
629
|
provingState!.reject(`${err}`);
|
|
594
630
|
} finally {
|
|
595
631
|
const index = this.pendingProvingJobs.indexOf(controller);
|
|
@@ -599,8 +635,11 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
599
635
|
}
|
|
600
636
|
};
|
|
601
637
|
|
|
602
|
-
|
|
603
|
-
|
|
638
|
+
void this.deferredJobQueue.put(async () => {
|
|
639
|
+
void safeJob();
|
|
640
|
+
// we yield here to the macro task queue such to give Nodejs a chance to run other operatoins in between enqueues
|
|
641
|
+
await sleep(0);
|
|
642
|
+
});
|
|
604
643
|
}
|
|
605
644
|
|
|
606
645
|
private async updateL1ToL2MessageTree(l1ToL2Messages: Fr[], db: MerkleTreeWriteOperations) {
|
|
@@ -674,12 +713,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
674
713
|
// Executes the next level of merge if all inputs are available
|
|
675
714
|
private enqueueBaseRollup(provingState: BlockProvingState, txIndex: number) {
|
|
676
715
|
if (!provingState.verifyState()) {
|
|
677
|
-
logger.debug('Not running base rollup, state invalid');
|
|
716
|
+
this.logger.debug('Not running base rollup, state invalid');
|
|
678
717
|
return;
|
|
679
718
|
}
|
|
680
719
|
|
|
681
720
|
if (!provingState.tryStartProvingBase(txIndex)) {
|
|
682
|
-
logger.debug(`Base rollup for tx ${txIndex} already started.`);
|
|
721
|
+
this.logger.debug(`Base rollup for tx ${txIndex} already started.`);
|
|
683
722
|
return;
|
|
684
723
|
}
|
|
685
724
|
|
|
@@ -687,7 +726,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
687
726
|
const { processedTx } = txProvingState;
|
|
688
727
|
const { rollupType, inputs } = txProvingState.getBaseRollupTypeAndInputs();
|
|
689
728
|
|
|
690
|
-
logger.debug(`Enqueuing deferred proving base rollup for ${processedTx.hash.toString()}`);
|
|
729
|
+
this.logger.debug(`Enqueuing deferred proving base rollup for ${processedTx.hash.toString()}`);
|
|
691
730
|
|
|
692
731
|
this.deferredProving(
|
|
693
732
|
provingState,
|
|
@@ -711,7 +750,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
711
750
|
},
|
|
712
751
|
),
|
|
713
752
|
result => {
|
|
714
|
-
logger.debug(`Completed proof for ${rollupType} for tx ${processedTx.hash.toString()}`);
|
|
753
|
+
this.logger.debug(`Completed proof for ${rollupType} for tx ${processedTx.hash.toString()}`);
|
|
715
754
|
validatePartialState(result.inputs.endTreeSnapshots, txProvingState.treeSnapshots);
|
|
716
755
|
const leafLocation = provingState.setBaseRollupProof(txIndex, result);
|
|
717
756
|
if (provingState.totalNumTxs === 1) {
|
|
@@ -727,7 +766,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
727
766
|
// Once completed, will enqueue the the public tx base rollup.
|
|
728
767
|
private getOrEnqueueChonkVerifier(provingState: BlockProvingState, txIndex: number) {
|
|
729
768
|
if (!provingState.verifyState()) {
|
|
730
|
-
logger.debug('Not running chonk verifier circuit, state invalid');
|
|
769
|
+
this.logger.debug('Not running chonk verifier circuit, state invalid');
|
|
731
770
|
return;
|
|
732
771
|
}
|
|
733
772
|
|
|
@@ -740,19 +779,19 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
740
779
|
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
741
780
|
>,
|
|
742
781
|
) => {
|
|
743
|
-
logger.debug(`Got chonk verifier proof for tx index: ${txIndex}`, { txHash });
|
|
782
|
+
this.logger.debug(`Got chonk verifier proof for tx index: ${txIndex}`, { txHash });
|
|
744
783
|
txProvingState.setPublicChonkVerifierProof(result);
|
|
745
784
|
this.provingState?.cachedChonkVerifierProofs.delete(txHash);
|
|
746
785
|
this.checkAndEnqueueBaseRollup(provingState, txIndex);
|
|
747
786
|
};
|
|
748
787
|
|
|
749
788
|
if (this.provingState?.cachedChonkVerifierProofs.has(txHash)) {
|
|
750
|
-
logger.debug(`Chonk verifier proof already enqueued for tx index: ${txIndex}`, { txHash });
|
|
789
|
+
this.logger.debug(`Chonk verifier proof already enqueued for tx index: ${txIndex}`, { txHash });
|
|
751
790
|
void this.provingState!.cachedChonkVerifierProofs.get(txHash)!.then(handleResult);
|
|
752
791
|
return;
|
|
753
792
|
}
|
|
754
793
|
|
|
755
|
-
logger.debug(`Enqueuing chonk verifier circuit for tx index: ${txIndex}`);
|
|
794
|
+
this.logger.debug(`Enqueuing chonk verifier circuit for tx index: ${txIndex}`);
|
|
756
795
|
this.doEnqueueChonkVerifier(txHash, txProvingState.getPublicChonkVerifierPrivateInputs(), handleResult);
|
|
757
796
|
}
|
|
758
797
|
|
|
@@ -768,7 +807,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
768
807
|
provingState: EpochProvingState | BlockProvingState = this.provingState!,
|
|
769
808
|
) {
|
|
770
809
|
if (!provingState.verifyState()) {
|
|
771
|
-
logger.debug('Not running chonk verifier circuit, state invalid');
|
|
810
|
+
this.logger.debug('Not running chonk verifier circuit, state invalid');
|
|
772
811
|
return;
|
|
773
812
|
}
|
|
774
813
|
|
|
@@ -791,12 +830,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
791
830
|
// Enqueues the next level of merge if all inputs are available
|
|
792
831
|
private enqueueMergeRollup(provingState: BlockProvingState, location: TreeNodeLocation) {
|
|
793
832
|
if (!provingState.verifyState()) {
|
|
794
|
-
logger.debug('Not running merge rollup. State no longer valid.');
|
|
833
|
+
this.logger.debug('Not running merge rollup. State no longer valid.');
|
|
795
834
|
return;
|
|
796
835
|
}
|
|
797
836
|
|
|
798
837
|
if (!provingState.tryStartProvingMerge(location)) {
|
|
799
|
-
logger.debug('Merge rollup already started.');
|
|
838
|
+
this.logger.debug('Merge rollup already started.');
|
|
800
839
|
return;
|
|
801
840
|
}
|
|
802
841
|
|
|
@@ -822,18 +861,18 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
822
861
|
// Executes the block root rollup circuit
|
|
823
862
|
private enqueueBlockRootRollup(provingState: BlockProvingState) {
|
|
824
863
|
if (!provingState.verifyState()) {
|
|
825
|
-
logger.debug('Not running block root rollup, state no longer valid');
|
|
864
|
+
this.logger.debug('Not running block root rollup, state no longer valid');
|
|
826
865
|
return;
|
|
827
866
|
}
|
|
828
867
|
|
|
829
868
|
if (!provingState.tryStartProvingBlockRoot()) {
|
|
830
|
-
logger.debug('Block root rollup already started.');
|
|
869
|
+
this.logger.debug('Block root rollup already started.');
|
|
831
870
|
return;
|
|
832
871
|
}
|
|
833
872
|
|
|
834
873
|
const { rollupType, inputs } = provingState.getBlockRootRollupTypeAndInputs();
|
|
835
874
|
|
|
836
|
-
logger.debug(`Enqueuing ${rollupType} for block ${provingState.blockNumber}.`);
|
|
875
|
+
this.logger.debug(`Enqueuing ${rollupType} for block ${provingState.blockNumber}.`);
|
|
837
876
|
|
|
838
877
|
this.deferredProving(
|
|
839
878
|
provingState,
|
|
@@ -858,18 +897,19 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
858
897
|
},
|
|
859
898
|
),
|
|
860
899
|
async result => {
|
|
861
|
-
|
|
862
|
-
await this.verifyBuiltBlockAgainstSyncedState(provingState);
|
|
863
|
-
|
|
864
|
-
logger.debug(`Completed ${rollupType} proof for block ${provingState.blockNumber}`);
|
|
900
|
+
this.logger.debug(`Completed ${rollupType} proof for block ${provingState.blockNumber}`);
|
|
865
901
|
|
|
866
902
|
const leafLocation = provingState.setBlockRootRollupProof(result);
|
|
867
903
|
const checkpointProvingState = provingState.parentCheckpoint;
|
|
868
904
|
|
|
905
|
+
// Verification is called from both here and setBlockCompleted. Whichever runs last
|
|
906
|
+
// will be the first to see all three pieces (header, proof output, archive) and run the checks.
|
|
907
|
+
await this.verifyBuiltBlockAgainstSyncedState(provingState);
|
|
908
|
+
|
|
869
909
|
if (checkpointProvingState.totalNumBlocks === 1) {
|
|
870
|
-
this.checkAndEnqueueCheckpointRootRollup(checkpointProvingState);
|
|
910
|
+
await this.checkAndEnqueueCheckpointRootRollup(checkpointProvingState);
|
|
871
911
|
} else {
|
|
872
|
-
this.checkAndEnqueueNextBlockMergeRollup(checkpointProvingState, leafLocation);
|
|
912
|
+
await this.checkAndEnqueueNextBlockMergeRollup(checkpointProvingState, leafLocation);
|
|
873
913
|
}
|
|
874
914
|
},
|
|
875
915
|
);
|
|
@@ -883,12 +923,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
883
923
|
baseParityIndex: number,
|
|
884
924
|
) {
|
|
885
925
|
if (!provingState.verifyState()) {
|
|
886
|
-
logger.debug('Not running base parity. State no longer valid.');
|
|
926
|
+
this.logger.debug('Not running base parity. State no longer valid.');
|
|
887
927
|
return;
|
|
888
928
|
}
|
|
889
929
|
|
|
890
930
|
if (!provingState.tryStartProvingBaseParity(baseParityIndex)) {
|
|
891
|
-
logger.warn(`Base parity ${baseParityIndex} already started.`);
|
|
931
|
+
this.logger.warn(`Base parity ${baseParityIndex} already started.`);
|
|
892
932
|
return;
|
|
893
933
|
}
|
|
894
934
|
|
|
@@ -923,12 +963,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
923
963
|
// Enqueues the root rollup proof if all inputs are available
|
|
924
964
|
private enqueueRootParityCircuit(provingState: BlockProvingState) {
|
|
925
965
|
if (!provingState.verifyState()) {
|
|
926
|
-
logger.debug('Not running root parity. State no longer valid.');
|
|
966
|
+
this.logger.debug('Not running root parity. State no longer valid.');
|
|
927
967
|
return;
|
|
928
968
|
}
|
|
929
969
|
|
|
930
970
|
if (!provingState.tryStartProvingRootParity()) {
|
|
931
|
-
logger.debug('Root parity already started.');
|
|
971
|
+
this.logger.debug('Root parity already started.');
|
|
932
972
|
return;
|
|
933
973
|
}
|
|
934
974
|
|
|
@@ -955,12 +995,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
955
995
|
// Enqueues the next level of merge if all inputs are available
|
|
956
996
|
private enqueueBlockMergeRollup(provingState: CheckpointProvingState, location: TreeNodeLocation) {
|
|
957
997
|
if (!provingState.verifyState()) {
|
|
958
|
-
logger.debug('Not running block merge rollup. State no longer valid.');
|
|
998
|
+
this.logger.debug('Not running block merge rollup. State no longer valid.');
|
|
959
999
|
return;
|
|
960
1000
|
}
|
|
961
1001
|
|
|
962
1002
|
if (!provingState.tryStartProvingBlockMerge(location)) {
|
|
963
|
-
logger.debug('Block merge rollup already started.');
|
|
1003
|
+
this.logger.debug('Block merge rollup already started.');
|
|
964
1004
|
return;
|
|
965
1005
|
}
|
|
966
1006
|
|
|
@@ -975,29 +1015,29 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
975
1015
|
},
|
|
976
1016
|
signal => this.prover.getBlockMergeRollupProof(inputs, signal, provingState.epochNumber),
|
|
977
1017
|
),
|
|
978
|
-
result => {
|
|
1018
|
+
async result => {
|
|
979
1019
|
provingState.setBlockMergeRollupProof(location, result);
|
|
980
|
-
this.checkAndEnqueueNextBlockMergeRollup(provingState, location);
|
|
1020
|
+
await this.checkAndEnqueueNextBlockMergeRollup(provingState, location);
|
|
981
1021
|
},
|
|
982
1022
|
);
|
|
983
1023
|
}
|
|
984
1024
|
|
|
985
|
-
private enqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
|
|
1025
|
+
private async enqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
|
|
986
1026
|
if (!provingState.verifyState()) {
|
|
987
|
-
logger.debug('Not running checkpoint root rollup. State no longer valid.');
|
|
1027
|
+
this.logger.debug('Not running checkpoint root rollup. State no longer valid.');
|
|
988
1028
|
return;
|
|
989
1029
|
}
|
|
990
1030
|
|
|
991
1031
|
if (!provingState.tryStartProvingCheckpointRoot()) {
|
|
992
|
-
logger.debug('Checkpoint root rollup already started.');
|
|
1032
|
+
this.logger.debug('Checkpoint root rollup already started.');
|
|
993
1033
|
return;
|
|
994
1034
|
}
|
|
995
1035
|
|
|
996
1036
|
const rollupType = provingState.getCheckpointRootRollupType();
|
|
997
1037
|
|
|
998
|
-
logger.debug(`Enqueuing ${rollupType} for checkpoint ${provingState.index}.`);
|
|
1038
|
+
this.logger.debug(`Enqueuing ${rollupType} for checkpoint ${provingState.index}.`);
|
|
999
1039
|
|
|
1000
|
-
const inputs = provingState.getCheckpointRootRollupInputs();
|
|
1040
|
+
const inputs = await provingState.getCheckpointRootRollupInputs();
|
|
1001
1041
|
|
|
1002
1042
|
this.deferredProving(
|
|
1003
1043
|
provingState,
|
|
@@ -1019,7 +1059,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1019
1059
|
const computedEndBlobAccumulatorState = provingState.getEndBlobAccumulator()!.toBlobAccumulator();
|
|
1020
1060
|
const circuitEndBlobAccumulatorState = result.inputs.endBlobAccumulator;
|
|
1021
1061
|
if (!circuitEndBlobAccumulatorState.equals(computedEndBlobAccumulatorState)) {
|
|
1022
|
-
logger.error(
|
|
1062
|
+
this.logger.error(
|
|
1023
1063
|
`Blob accumulator state mismatch.\nCircuit: ${inspect(circuitEndBlobAccumulatorState)}\nComputed: ${inspect(
|
|
1024
1064
|
computedEndBlobAccumulatorState,
|
|
1025
1065
|
)}`,
|
|
@@ -1028,7 +1068,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1028
1068
|
return;
|
|
1029
1069
|
}
|
|
1030
1070
|
|
|
1031
|
-
logger.debug(`Completed ${rollupType} proof for checkpoint ${provingState.index}.`);
|
|
1071
|
+
this.logger.debug(`Completed ${rollupType} proof for checkpoint ${provingState.index}.`);
|
|
1032
1072
|
|
|
1033
1073
|
const leafLocation = provingState.setCheckpointRootRollupProof(result);
|
|
1034
1074
|
const epochProvingState = provingState.parentEpoch;
|
|
@@ -1044,12 +1084,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1044
1084
|
|
|
1045
1085
|
private enqueueCheckpointMergeRollup(provingState: EpochProvingState, location: TreeNodeLocation) {
|
|
1046
1086
|
if (!provingState.verifyState()) {
|
|
1047
|
-
logger.debug('Not running checkpoint merge rollup. State no longer valid.');
|
|
1087
|
+
this.logger.debug('Not running checkpoint merge rollup. State no longer valid.');
|
|
1048
1088
|
return;
|
|
1049
1089
|
}
|
|
1050
1090
|
|
|
1051
1091
|
if (!provingState.tryStartProvingCheckpointMerge(location)) {
|
|
1052
|
-
logger.debug('Checkpoint merge rollup already started.');
|
|
1092
|
+
this.logger.debug('Checkpoint merge rollup already started.');
|
|
1053
1093
|
return;
|
|
1054
1094
|
}
|
|
1055
1095
|
|
|
@@ -1066,7 +1106,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1066
1106
|
signal => this.prover.getCheckpointMergeRollupProof(inputs, signal, provingState.epochNumber),
|
|
1067
1107
|
),
|
|
1068
1108
|
result => {
|
|
1069
|
-
logger.debug('Completed proof for checkpoint merge rollup.');
|
|
1109
|
+
this.logger.debug('Completed proof for checkpoint merge rollup.');
|
|
1070
1110
|
provingState.setCheckpointMergeRollupProof(location, result);
|
|
1071
1111
|
this.checkAndEnqueueNextCheckpointMergeRollup(provingState, location);
|
|
1072
1112
|
},
|
|
@@ -1075,16 +1115,16 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1075
1115
|
|
|
1076
1116
|
private enqueueEpochPadding(provingState: EpochProvingState) {
|
|
1077
1117
|
if (!provingState.verifyState()) {
|
|
1078
|
-
logger.debug('Not running epoch padding. State no longer valid.');
|
|
1118
|
+
this.logger.debug('Not running epoch padding. State no longer valid.');
|
|
1079
1119
|
return;
|
|
1080
1120
|
}
|
|
1081
1121
|
|
|
1082
1122
|
if (!provingState.tryStartProvingPaddingCheckpoint()) {
|
|
1083
|
-
logger.debug('Padding checkpoint already started.');
|
|
1123
|
+
this.logger.debug('Padding checkpoint already started.');
|
|
1084
1124
|
return;
|
|
1085
1125
|
}
|
|
1086
1126
|
|
|
1087
|
-
logger.debug('Padding epoch proof with a padding block root proof.');
|
|
1127
|
+
this.logger.debug('Padding epoch proof with a padding block root proof.');
|
|
1088
1128
|
|
|
1089
1129
|
const inputs = provingState.getPaddingCheckpointInputs();
|
|
1090
1130
|
|
|
@@ -1099,7 +1139,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1099
1139
|
signal => this.prover.getCheckpointPaddingRollupProof(inputs, signal, provingState.epochNumber),
|
|
1100
1140
|
),
|
|
1101
1141
|
result => {
|
|
1102
|
-
logger.debug('Completed proof for padding checkpoint.');
|
|
1142
|
+
this.logger.debug('Completed proof for padding checkpoint.');
|
|
1103
1143
|
provingState.setCheckpointPaddingProof(result);
|
|
1104
1144
|
this.checkAndEnqueueRootRollup(provingState);
|
|
1105
1145
|
},
|
|
@@ -1109,11 +1149,11 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1109
1149
|
// Executes the root rollup circuit
|
|
1110
1150
|
private enqueueRootRollup(provingState: EpochProvingState) {
|
|
1111
1151
|
if (!provingState.verifyState()) {
|
|
1112
|
-
logger.debug('Not running root rollup, state no longer valid');
|
|
1152
|
+
this.logger.debug('Not running root rollup, state no longer valid');
|
|
1113
1153
|
return;
|
|
1114
1154
|
}
|
|
1115
1155
|
|
|
1116
|
-
logger.debug(`Preparing root rollup`);
|
|
1156
|
+
this.logger.debug(`Preparing root rollup`);
|
|
1117
1157
|
|
|
1118
1158
|
const inputs = provingState.getRootRollupInputs();
|
|
1119
1159
|
|
|
@@ -1128,7 +1168,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1128
1168
|
signal => this.prover.getRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
1129
1169
|
),
|
|
1130
1170
|
result => {
|
|
1131
|
-
logger.verbose(`Orchestrator completed root rollup for epoch ${provingState.epochNumber}`);
|
|
1171
|
+
this.logger.verbose(`Orchestrator completed root rollup for epoch ${provingState.epochNumber}`);
|
|
1132
1172
|
provingState.setRootRollupProof(result);
|
|
1133
1173
|
provingState.resolve({ status: 'success' });
|
|
1134
1174
|
},
|
|
@@ -1150,32 +1190,35 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1150
1190
|
|
|
1151
1191
|
private checkAndEnqueueBlockRootRollup(provingState: BlockProvingState) {
|
|
1152
1192
|
if (!provingState.isReadyForBlockRootRollup()) {
|
|
1153
|
-
logger.debug('Not ready for block root rollup');
|
|
1193
|
+
this.logger.debug('Not ready for block root rollup');
|
|
1154
1194
|
return;
|
|
1155
1195
|
}
|
|
1156
1196
|
|
|
1157
1197
|
this.enqueueBlockRootRollup(provingState);
|
|
1158
1198
|
}
|
|
1159
1199
|
|
|
1160
|
-
private checkAndEnqueueNextBlockMergeRollup(
|
|
1200
|
+
private async checkAndEnqueueNextBlockMergeRollup(
|
|
1201
|
+
provingState: CheckpointProvingState,
|
|
1202
|
+
currentLocation: TreeNodeLocation,
|
|
1203
|
+
) {
|
|
1161
1204
|
if (!provingState.isReadyForBlockMerge(currentLocation)) {
|
|
1162
1205
|
return;
|
|
1163
1206
|
}
|
|
1164
1207
|
|
|
1165
1208
|
const parentLocation = provingState.getParentLocation(currentLocation);
|
|
1166
1209
|
if (parentLocation.level === 0) {
|
|
1167
|
-
this.checkAndEnqueueCheckpointRootRollup(provingState);
|
|
1210
|
+
await this.checkAndEnqueueCheckpointRootRollup(provingState);
|
|
1168
1211
|
} else {
|
|
1169
1212
|
this.enqueueBlockMergeRollup(provingState, parentLocation);
|
|
1170
1213
|
}
|
|
1171
1214
|
}
|
|
1172
1215
|
|
|
1173
|
-
private checkAndEnqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
|
|
1216
|
+
private async checkAndEnqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
|
|
1174
1217
|
if (!provingState.isReadyForCheckpointRoot()) {
|
|
1175
1218
|
return;
|
|
1176
1219
|
}
|
|
1177
1220
|
|
|
1178
|
-
this.enqueueCheckpointRootRollup(provingState);
|
|
1221
|
+
await this.enqueueCheckpointRootRollup(provingState);
|
|
1179
1222
|
}
|
|
1180
1223
|
|
|
1181
1224
|
private checkAndEnqueueNextCheckpointMergeRollup(provingState: EpochProvingState, currentLocation: TreeNodeLocation) {
|
|
@@ -1193,7 +1236,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1193
1236
|
|
|
1194
1237
|
private checkAndEnqueueRootRollup(provingState: EpochProvingState) {
|
|
1195
1238
|
if (!provingState.isReadyForRootRollup()) {
|
|
1196
|
-
logger.debug('Not ready for root rollup');
|
|
1239
|
+
this.logger.debug('Not ready for root rollup');
|
|
1197
1240
|
return;
|
|
1198
1241
|
}
|
|
1199
1242
|
|
|
@@ -1208,14 +1251,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1208
1251
|
*/
|
|
1209
1252
|
private enqueueVM(provingState: BlockProvingState, txIndex: number) {
|
|
1210
1253
|
if (!provingState.verifyState()) {
|
|
1211
|
-
logger.debug(`Not running VM circuit as state is no longer valid`);
|
|
1254
|
+
this.logger.debug(`Not running VM circuit as state is no longer valid`);
|
|
1212
1255
|
return;
|
|
1213
1256
|
}
|
|
1214
1257
|
|
|
1215
1258
|
const txProvingState = provingState.getTxProvingState(txIndex);
|
|
1216
1259
|
|
|
1217
|
-
// This function tries to do AVM proving. If there is a failure, it fakes the proof unless AVM_PROVING_STRICT is defined.
|
|
1218
|
-
// Nothing downstream depends on the AVM proof yet. So having this mode lets us incrementally build the AVM circuit.
|
|
1219
1260
|
const doAvmProving = wrapCallbackInSpan(
|
|
1220
1261
|
this.tracer,
|
|
1221
1262
|
'ProvingOrchestrator.prover.getAvmProof',
|
|
@@ -1224,36 +1265,13 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1224
1265
|
},
|
|
1225
1266
|
async (signal: AbortSignal) => {
|
|
1226
1267
|
const inputs = txProvingState.getAvmInputs();
|
|
1227
|
-
|
|
1228
|
-
// TODO(#14234)[Unconditional PIs validation]: Remove the whole try-catch logic and
|
|
1229
|
-
// just keep the next line but removing the second argument (false).
|
|
1230
|
-
return await this.prover.getAvmProof(inputs, false, signal, provingState.epochNumber);
|
|
1231
|
-
} catch (err) {
|
|
1232
|
-
if (process.env.AVM_PROVING_STRICT) {
|
|
1233
|
-
logger.error(`Error thrown when proving AVM circuit with AVM_PROVING_STRICT on`, err);
|
|
1234
|
-
throw err;
|
|
1235
|
-
} else {
|
|
1236
|
-
logger.warn(
|
|
1237
|
-
`Error thrown when proving AVM circuit but AVM_PROVING_STRICT is off. Use snapshotted
|
|
1238
|
-
AVM inputs and carrying on. ${inspect(err)}.`,
|
|
1239
|
-
);
|
|
1240
|
-
|
|
1241
|
-
try {
|
|
1242
|
-
this.metrics.incAvmFallback();
|
|
1243
|
-
const snapshotAvmPrivateInputs = readAvmMinimalPublicTxInputsFromFile();
|
|
1244
|
-
return await this.prover.getAvmProof(snapshotAvmPrivateInputs, true, signal, provingState.epochNumber);
|
|
1245
|
-
} catch (err) {
|
|
1246
|
-
logger.error(`Error thrown when proving snapshotted AVM inputs.`, err);
|
|
1247
|
-
throw err;
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
}
|
|
1268
|
+
return await this.prover.getAvmProof(inputs, signal, provingState.epochNumber);
|
|
1251
1269
|
},
|
|
1252
1270
|
);
|
|
1253
1271
|
|
|
1254
|
-
this.deferredProving(provingState, doAvmProving,
|
|
1255
|
-
logger.debug(`Proven VM for tx index: ${txIndex}`);
|
|
1256
|
-
txProvingState.setAvmProof(
|
|
1272
|
+
this.deferredProving(provingState, doAvmProving, proof => {
|
|
1273
|
+
this.logger.debug(`Proven VM for tx index: ${txIndex}`);
|
|
1274
|
+
txProvingState.setAvmProof(proof);
|
|
1257
1275
|
this.checkAndEnqueueBaseRollup(provingState, txIndex);
|
|
1258
1276
|
});
|
|
1259
1277
|
}
|
|
@@ -1265,7 +1283,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1265
1283
|
}
|
|
1266
1284
|
|
|
1267
1285
|
// We must have completed all proving (chonk verifier proof and (if required) vm proof are generated), we now move to the base rollup.
|
|
1268
|
-
logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`);
|
|
1286
|
+
this.logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`);
|
|
1269
1287
|
|
|
1270
1288
|
this.enqueueBaseRollup(provingState, txIndex);
|
|
1271
1289
|
}
|