@aztec/prover-client 0.0.0-test.1 → 0.0.1-commit.023c3e5
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 +8 -8
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +12 -2
- 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 +47 -0
- package/dest/light/lightweight_checkpoint_builder.d.ts.map +1 -0
- package/dest/light/lightweight_checkpoint_builder.js +200 -0
- package/dest/mocks/fixtures.d.ts +8 -8
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +36 -17
- package/dest/mocks/test_context.d.ts +43 -32
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +149 -87
- package/dest/orchestrator/block-building-helpers.d.ts +37 -30
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +170 -189
- package/dest/orchestrator/block-proving-state.d.ts +70 -48
- package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/block-proving-state.js +282 -177
- package/dest/orchestrator/checkpoint-proving-state.d.ts +76 -0
- package/dest/orchestrator/checkpoint-proving-state.d.ts.map +1 -0
- package/dest/orchestrator/checkpoint-proving-state.js +243 -0
- package/dest/orchestrator/epoch-proving-state.d.ts +43 -28
- package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/epoch-proving-state.js +177 -73
- package/dest/orchestrator/index.d.ts +1 -1
- package/dest/orchestrator/orchestrator.d.ts +53 -35
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +855 -302
- package/dest/orchestrator/orchestrator_metrics.d.ts +1 -1
- package/dest/orchestrator/orchestrator_metrics.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator_metrics.js +2 -6
- package/dest/orchestrator/tx-proving-state.d.ts +15 -12
- package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/tx-proving-state.js +27 -44
- 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 +5 -5
- package/dest/prover-client/prover-client.d.ts.map +1 -1
- package/dest/prover-client/prover-client.js +11 -7
- package/dest/prover-client/server-epoch-prover.d.ts +16 -12
- package/dest/prover-client/server-epoch-prover.d.ts.map +1 -1
- package/dest/prover-client/server-epoch-prover.js +11 -11
- package/dest/proving_broker/broker_prover_facade.d.ts +28 -19
- package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
- package/dest/proving_broker/broker_prover_facade.js +62 -43
- package/dest/proving_broker/config.d.ts +23 -10
- package/dest/proving_broker/config.d.ts.map +1 -1
- package/dest/proving_broker/config.js +29 -6
- package/dest/proving_broker/factory.d.ts +2 -2
- package/dest/proving_broker/factory.d.ts.map +1 -1
- package/dest/proving_broker/factory.js +5 -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 -2
- package/dest/proving_broker/proof_store/factory.js +1 -1
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts +1 -1
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts.map +1 -1
- package/dest/proving_broker/proof_store/gcs_proof_store.js +1 -0
- package/dest/proving_broker/proof_store/index.d.ts +2 -1
- package/dest/proving_broker/proof_store/index.d.ts.map +1 -1
- package/dest/proving_broker/proof_store/index.js +1 -0
- 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 +8 -12
- package/dest/proving_broker/proving_agent.d.ts.map +1 -1
- package/dest/proving_broker/proving_agent.js +86 -65
- package/dest/proving_broker/proving_broker.d.ts +13 -4
- package/dest/proving_broker/proving_broker.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker.js +40 -33
- 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/memory.js +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 +401 -11
- 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 +1 -1
- package/dest/proving_broker/proving_broker_instrumentation.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker_instrumentation.js +15 -35
- package/dest/proving_broker/proving_job_controller.d.ts +11 -10
- package/dest/proving_broker/proving_job_controller.d.ts.map +1 -1
- package/dest/proving_broker/proving_job_controller.js +92 -62
- package/dest/proving_broker/rpc.d.ts +4 -6
- package/dest/proving_broker/rpc.d.ts.map +1 -1
- package/dest/proving_broker/rpc.js +1 -4
- package/dest/test/mock_proof_store.d.ts +9 -0
- package/dest/test/mock_proof_store.d.ts.map +1 -0
- package/dest/test/mock_proof_store.js +10 -0
- package/dest/test/mock_prover.d.ts +23 -17
- package/dest/test/mock_prover.d.ts.map +1 -1
- package/dest/test/mock_prover.js +38 -20
- package/package.json +33 -31
- package/src/config.ts +25 -9
- package/src/light/index.ts +1 -0
- package/src/light/lightweight_checkpoint_builder.ts +289 -0
- package/src/mocks/fixtures.ts +46 -40
- package/src/mocks/test_context.ts +223 -116
- package/src/orchestrator/block-building-helpers.ts +258 -334
- package/src/orchestrator/block-proving-state.ts +325 -231
- package/src/orchestrator/checkpoint-proving-state.ts +349 -0
- package/src/orchestrator/epoch-proving-state.ts +237 -111
- package/src/orchestrator/orchestrator.ts +653 -343
- package/src/orchestrator/orchestrator_metrics.ts +2 -6
- package/src/orchestrator/tx-proving-state.ts +48 -66
- package/src/prover-client/factory.ts +6 -2
- package/src/prover-client/prover-client.ts +41 -29
- package/src/prover-client/server-epoch-prover.ts +40 -22
- package/src/proving_broker/broker_prover_facade.ts +212 -131
- package/src/proving_broker/config.ts +34 -7
- package/src/proving_broker/factory.ts +2 -1
- package/src/proving_broker/fixtures.ts +8 -3
- package/src/proving_broker/proof_store/factory.ts +1 -1
- package/src/proving_broker/proof_store/gcs_proof_store.ts +5 -1
- package/src/proving_broker/proof_store/index.ts +1 -0
- package/src/proving_broker/proof_store/inline_proof_store.ts +1 -1
- package/src/proving_broker/proving_agent.ts +95 -66
- package/src/proving_broker/proving_broker.ts +57 -41
- package/src/proving_broker/proving_broker_database/memory.ts +3 -2
- package/src/proving_broker/proving_broker_database/persisted.ts +29 -13
- package/src/proving_broker/proving_broker_database.ts +2 -1
- package/src/proving_broker/proving_broker_instrumentation.ts +14 -35
- package/src/proving_broker/proving_job_controller.ts +100 -83
- package/src/proving_broker/rpc.ts +1 -6
- package/src/test/mock_proof_store.ts +14 -0
- package/src/test/mock_prover.ts +156 -64
- package/dest/bin/get-proof-inputs.d.ts +0 -2
- package/dest/bin/get-proof-inputs.d.ts.map +0 -1
- package/dest/bin/get-proof-inputs.js +0 -51
- package/dest/block_builder/index.d.ts +0 -6
- package/dest/block_builder/index.d.ts.map +0 -1
- package/dest/block_builder/index.js +0 -1
- package/dest/block_builder/light.d.ts +0 -33
- package/dest/block_builder/light.d.ts.map +0 -1
- package/dest/block_builder/light.js +0 -82
- 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/bin/get-proof-inputs.ts +0 -59
- package/src/block_builder/index.ts +0 -6
- package/src/block_builder/light.ts +0 -101
- package/src/proving_broker/proving_agent_instrumentation.ts +0 -21
|
@@ -1,43 +1,48 @@
|
|
|
1
|
+
import { BatchedBlob, FinalBlobBatchingChallenges, SpongeBlob } from '@aztec/blob-lib/types';
|
|
1
2
|
import {
|
|
2
|
-
AVM_PROOF_LENGTH_IN_FIELDS,
|
|
3
|
-
AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS,
|
|
4
3
|
L1_TO_L2_MSG_SUBTREE_HEIGHT,
|
|
5
|
-
|
|
4
|
+
L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
|
|
5
|
+
NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
|
|
6
6
|
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
7
7
|
NUM_BASE_PARITY_PER_ROOT_PARITY,
|
|
8
|
-
type TUBE_PROOF_LENGTH,
|
|
9
8
|
} from '@aztec/constants';
|
|
10
|
-
import {
|
|
9
|
+
import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
|
|
10
|
+
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
11
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
11
12
|
import { AbortError } from '@aztec/foundation/error';
|
|
12
|
-
import {
|
|
13
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
13
|
+
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
14
14
|
import { promiseWithResolvers } from '@aztec/foundation/promise';
|
|
15
15
|
import { assertLength } from '@aztec/foundation/serialize';
|
|
16
16
|
import { pushTestData } from '@aztec/foundation/testing';
|
|
17
17
|
import { elapsed } from '@aztec/foundation/timer';
|
|
18
18
|
import type { TreeNodeLocation } from '@aztec/foundation/trees';
|
|
19
|
-
import {
|
|
20
|
-
import { L2Block } from '@aztec/stdlib/block';
|
|
19
|
+
import { EthAddress } from '@aztec/stdlib/block';
|
|
21
20
|
import type {
|
|
22
21
|
EpochProver,
|
|
23
22
|
ForkMerkleTreeOperations,
|
|
24
23
|
MerkleTreeWriteOperations,
|
|
25
|
-
|
|
24
|
+
PublicInputsAndRecursiveProof,
|
|
25
|
+
ReadonlyWorldStateAccess,
|
|
26
26
|
ServerCircuitProver,
|
|
27
27
|
} from '@aztec/stdlib/interfaces/server';
|
|
28
|
-
import {
|
|
29
|
-
import { makeEmptyRecursiveProof } from '@aztec/stdlib/proofs';
|
|
28
|
+
import type { Proof } from '@aztec/stdlib/proofs';
|
|
30
29
|
import {
|
|
31
30
|
type BaseRollupHints,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
BlockRootEmptyTxFirstRollupPrivateInputs,
|
|
32
|
+
BlockRootFirstRollupPrivateInputs,
|
|
33
|
+
BlockRootSingleTxFirstRollupPrivateInputs,
|
|
34
|
+
BlockRootSingleTxRollupPrivateInputs,
|
|
35
|
+
CheckpointConstantData,
|
|
36
|
+
CheckpointRootSingleBlockRollupPrivateInputs,
|
|
37
|
+
PrivateTxBaseRollupPrivateInputs,
|
|
38
|
+
PublicChonkVerifierPrivateInputs,
|
|
39
|
+
PublicChonkVerifierPublicInputs,
|
|
40
|
+
RootRollupPublicInputs,
|
|
36
41
|
} from '@aztec/stdlib/rollup';
|
|
37
42
|
import type { CircuitName } from '@aztec/stdlib/stats';
|
|
38
43
|
import { type AppendOnlyTreeSnapshot, MerkleTreeId } from '@aztec/stdlib/trees';
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
44
|
+
import type { BlockHeader, ProcessedTx, Tx } from '@aztec/stdlib/tx';
|
|
45
|
+
import type { UInt64 } from '@aztec/stdlib/types';
|
|
41
46
|
import {
|
|
42
47
|
Attributes,
|
|
43
48
|
type TelemetryClient,
|
|
@@ -50,20 +55,26 @@ import {
|
|
|
50
55
|
import { inspect } from 'util';
|
|
51
56
|
|
|
52
57
|
import {
|
|
53
|
-
|
|
54
|
-
|
|
58
|
+
buildHeaderFromCircuitOutputs,
|
|
59
|
+
getLastSiblingPath,
|
|
60
|
+
getPublicChonkVerifierPrivateInputsFromTx,
|
|
55
61
|
getRootTreeSiblingPath,
|
|
56
62
|
getSubtreeSiblingPath,
|
|
57
63
|
getTreeSnapshot,
|
|
64
|
+
insertSideEffectsAndBuildBaseRollupHints,
|
|
58
65
|
validatePartialState,
|
|
59
66
|
validateTx,
|
|
60
67
|
} from './block-building-helpers.js';
|
|
61
68
|
import type { BlockProvingState } from './block-proving-state.js';
|
|
69
|
+
import type { CheckpointProvingState } from './checkpoint-proving-state.js';
|
|
62
70
|
import { EpochProvingState, type ProvingResult, type TreeSnapshots } from './epoch-proving-state.js';
|
|
63
71
|
import { ProvingOrchestratorMetrics } from './orchestrator_metrics.js';
|
|
64
72
|
import { TxProvingState } from './tx-proving-state.js';
|
|
65
73
|
|
|
66
|
-
|
|
74
|
+
type WorldStateFork = {
|
|
75
|
+
fork: MerkleTreeWriteOperations;
|
|
76
|
+
cleanupPromise: Promise<void> | undefined;
|
|
77
|
+
};
|
|
67
78
|
|
|
68
79
|
/**
|
|
69
80
|
* Implements an event driven proving scheduler to build the recursive proof tree. The idea being:
|
|
@@ -85,14 +96,19 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
85
96
|
|
|
86
97
|
private provingPromise: Promise<ProvingResult> | undefined = undefined;
|
|
87
98
|
private metrics: ProvingOrchestratorMetrics;
|
|
88
|
-
|
|
99
|
+
// eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
|
|
100
|
+
private dbs: Map<BlockNumber, WorldStateFork> = new Map();
|
|
101
|
+
private logger: Logger;
|
|
89
102
|
|
|
90
103
|
constructor(
|
|
91
|
-
private dbProvider: ForkMerkleTreeOperations,
|
|
104
|
+
private dbProvider: ReadonlyWorldStateAccess & ForkMerkleTreeOperations,
|
|
92
105
|
private prover: ServerCircuitProver,
|
|
93
|
-
private readonly proverId:
|
|
106
|
+
private readonly proverId: EthAddress,
|
|
107
|
+
private readonly cancelJobsOnStop: boolean = false,
|
|
94
108
|
telemetryClient: TelemetryClient = getTelemetryClient(),
|
|
109
|
+
bindings?: LoggerBindings,
|
|
95
110
|
) {
|
|
111
|
+
this.logger = createLogger('prover-client:orchestrator', bindings);
|
|
96
112
|
this.metrics = new ProvingOrchestratorMetrics(telemetryClient, 'ProvingOrchestrator');
|
|
97
113
|
}
|
|
98
114
|
|
|
@@ -100,73 +116,167 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
100
116
|
return this.metrics.tracer;
|
|
101
117
|
}
|
|
102
118
|
|
|
103
|
-
public getProverId():
|
|
119
|
+
public getProverId(): EthAddress {
|
|
104
120
|
return this.proverId;
|
|
105
121
|
}
|
|
106
122
|
|
|
123
|
+
public getNumActiveForks() {
|
|
124
|
+
return this.dbs.size;
|
|
125
|
+
}
|
|
126
|
+
|
|
107
127
|
public stop(): Promise<void> {
|
|
108
128
|
this.cancel();
|
|
109
129
|
return Promise.resolve();
|
|
110
130
|
}
|
|
111
131
|
|
|
112
|
-
public startNewEpoch(
|
|
132
|
+
public startNewEpoch(
|
|
133
|
+
epochNumber: EpochNumber,
|
|
134
|
+
totalNumCheckpoints: number,
|
|
135
|
+
finalBlobBatchingChallenges: FinalBlobBatchingChallenges,
|
|
136
|
+
) {
|
|
137
|
+
if (this.provingState?.verifyState()) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`Cannot start epoch ${epochNumber} when epoch ${this.provingState.epochNumber} is still being processed.`,
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
113
143
|
const { promise: _promise, resolve, reject } = promiseWithResolvers<ProvingResult>();
|
|
114
144
|
const promise = _promise.catch((reason): ProvingResult => ({ status: 'failure', reason }));
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
145
|
+
this.logger.info(`Starting epoch ${epochNumber} with ${totalNumCheckpoints} checkpoints.`);
|
|
146
|
+
this.provingState = new EpochProvingState(
|
|
147
|
+
epochNumber,
|
|
148
|
+
totalNumCheckpoints,
|
|
149
|
+
finalBlobBatchingChallenges,
|
|
150
|
+
provingState => this.checkAndEnqueueCheckpointRootRollup(provingState),
|
|
151
|
+
resolve,
|
|
152
|
+
reject,
|
|
153
|
+
);
|
|
120
154
|
this.provingPromise = promise;
|
|
121
155
|
}
|
|
122
156
|
|
|
123
157
|
/**
|
|
124
|
-
* Starts
|
|
125
|
-
* @param
|
|
126
|
-
* @param
|
|
127
|
-
* @
|
|
158
|
+
* Starts a new checkpoint.
|
|
159
|
+
* @param checkpointIndex - The index of the checkpoint in the epoch.
|
|
160
|
+
* @param constants - The constants for this checkpoint.
|
|
161
|
+
* @param l1ToL2Messages - The set of L1 to L2 messages to be inserted at the beginning of this checkpoint.
|
|
162
|
+
* @param totalNumBlocks - The total number of blocks expected in the checkpoint (must be at least one).
|
|
163
|
+
* @param headerOfLastBlockInPreviousCheckpoint - The header of the last block in the previous checkpoint.
|
|
128
164
|
*/
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
165
|
+
public async startNewCheckpoint(
|
|
166
|
+
checkpointIndex: number,
|
|
167
|
+
constants: CheckpointConstantData,
|
|
168
|
+
l1ToL2Messages: Fr[],
|
|
169
|
+
totalNumBlocks: number,
|
|
170
|
+
headerOfLastBlockInPreviousCheckpoint: BlockHeader,
|
|
171
|
+
) {
|
|
133
172
|
if (!this.provingState) {
|
|
134
|
-
throw new Error(
|
|
173
|
+
throw new Error('Empty epoch proving state. Call startNewEpoch before starting a checkpoint.');
|
|
135
174
|
}
|
|
136
175
|
|
|
137
|
-
if (!this.provingState
|
|
138
|
-
throw new Error(`Epoch not accepting further
|
|
176
|
+
if (!this.provingState.isAcceptingCheckpoints()) {
|
|
177
|
+
throw new Error(`Epoch not accepting further checkpoints.`);
|
|
139
178
|
}
|
|
140
179
|
|
|
141
|
-
|
|
142
|
-
|
|
180
|
+
// Fork world state at the end of the immediately previous block.
|
|
181
|
+
const lastBlockNumber = headerOfLastBlockInPreviousCheckpoint.globalVariables.blockNumber;
|
|
182
|
+
const db = await this.dbProvider.fork(lastBlockNumber);
|
|
183
|
+
|
|
184
|
+
const firstBlockNumber = BlockNumber(lastBlockNumber + 1);
|
|
185
|
+
this.dbs.set(firstBlockNumber, { fork: db, cleanupPromise: undefined });
|
|
186
|
+
|
|
187
|
+
// Get archive sibling path before any block in this checkpoint lands.
|
|
188
|
+
const lastArchiveSiblingPath = await getLastSiblingPath(MerkleTreeId.ARCHIVE, db);
|
|
189
|
+
|
|
190
|
+
// Insert all the l1 to l2 messages into the db. And get the states before and after the insertion.
|
|
191
|
+
const {
|
|
192
|
+
lastL1ToL2MessageTreeSnapshot,
|
|
193
|
+
lastL1ToL2MessageSubtreeRootSiblingPath,
|
|
194
|
+
newL1ToL2MessageTreeSnapshot,
|
|
195
|
+
newL1ToL2MessageSubtreeRootSiblingPath,
|
|
196
|
+
} = await this.updateL1ToL2MessageTree(l1ToL2Messages, db);
|
|
197
|
+
|
|
198
|
+
this.provingState.startNewCheckpoint(
|
|
199
|
+
checkpointIndex,
|
|
200
|
+
constants,
|
|
201
|
+
totalNumBlocks,
|
|
202
|
+
headerOfLastBlockInPreviousCheckpoint,
|
|
203
|
+
lastArchiveSiblingPath,
|
|
204
|
+
l1ToL2Messages,
|
|
205
|
+
lastL1ToL2MessageTreeSnapshot,
|
|
206
|
+
lastL1ToL2MessageSubtreeRootSiblingPath,
|
|
207
|
+
newL1ToL2MessageTreeSnapshot,
|
|
208
|
+
newL1ToL2MessageSubtreeRootSiblingPath,
|
|
143
209
|
);
|
|
210
|
+
}
|
|
144
211
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
212
|
+
/**
|
|
213
|
+
* Starts off a new block
|
|
214
|
+
* @param blockNumber - The block number
|
|
215
|
+
* @param timestamp - The timestamp of the block. This is only required for constructing the private inputs for the
|
|
216
|
+
* block that doesn't have any txs.
|
|
217
|
+
* @param totalNumTxs - The total number of txs in the block
|
|
218
|
+
*/
|
|
219
|
+
@trackSpan('ProvingOrchestrator.startNewBlock', blockNumber => ({
|
|
220
|
+
[Attributes.BLOCK_NUMBER]: blockNumber,
|
|
221
|
+
}))
|
|
222
|
+
public async startNewBlock(blockNumber: BlockNumber, timestamp: UInt64, totalNumTxs: number) {
|
|
223
|
+
if (!this.provingState) {
|
|
224
|
+
throw new Error('Empty epoch proving state. Call startNewEpoch before starting a block.');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const checkpointProvingState = this.provingState.getCheckpointProvingStateByBlockNumber(blockNumber);
|
|
228
|
+
if (!checkpointProvingState) {
|
|
229
|
+
throw new Error(`Checkpoint not started. Call startNewCheckpoint first.`);
|
|
230
|
+
}
|
|
148
231
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
232
|
+
if (!checkpointProvingState.isAcceptingBlocks()) {
|
|
233
|
+
throw new Error(`Checkpoint not accepting further blocks.`);
|
|
234
|
+
}
|
|
152
235
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const newArchiveSiblingPath = await getRootTreeSiblingPath(MerkleTreeId.ARCHIVE, db);
|
|
236
|
+
const constants = checkpointProvingState.constants;
|
|
237
|
+
this.logger.info(`Starting block ${blockNumber} for slot ${constants.slotNumber}.`);
|
|
156
238
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
239
|
+
// Fork the db only when it's not already set. The db for the first block is set in `startNewCheckpoint`.
|
|
240
|
+
if (!this.dbs.has(blockNumber)) {
|
|
241
|
+
// Fork world state at the end of the immediately previous block
|
|
242
|
+
const db = await this.dbProvider.fork(BlockNumber(blockNumber - 1));
|
|
243
|
+
this.dbs.set(blockNumber, { fork: db, cleanupPromise: undefined });
|
|
244
|
+
}
|
|
245
|
+
const db = this.dbs.get(blockNumber)!.fork;
|
|
246
|
+
|
|
247
|
+
// Get archive snapshot and sibling path before any txs in this block lands.
|
|
248
|
+
const lastArchiveTreeSnapshot = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
249
|
+
const lastArchiveSiblingPath = await getRootTreeSiblingPath(MerkleTreeId.ARCHIVE, db);
|
|
250
|
+
|
|
251
|
+
const blockProvingState = checkpointProvingState.startNewBlock(
|
|
252
|
+
blockNumber,
|
|
253
|
+
timestamp,
|
|
254
|
+
totalNumTxs,
|
|
255
|
+
lastArchiveTreeSnapshot,
|
|
256
|
+
lastArchiveSiblingPath,
|
|
165
257
|
);
|
|
166
258
|
|
|
167
|
-
// Enqueue base parity circuits for the block
|
|
168
|
-
|
|
169
|
-
|
|
259
|
+
// Enqueue base parity circuits for the first block in the checkpoint.
|
|
260
|
+
if (blockProvingState.index === 0) {
|
|
261
|
+
for (let i = 0; i < NUM_BASE_PARITY_PER_ROOT_PARITY; i++) {
|
|
262
|
+
this.enqueueBaseParityCircuit(checkpointProvingState, blockProvingState, i);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Because `addTxs` won't be called for a block without txs, and that's where the sponge blob state is computed.
|
|
267
|
+
// We need to set its end sponge blob here, which will become the start sponge blob for the next block.
|
|
268
|
+
if (totalNumTxs === 0) {
|
|
269
|
+
const endState = await db.getStateReference();
|
|
270
|
+
blockProvingState.setEndState(endState);
|
|
271
|
+
|
|
272
|
+
const endSpongeBlob = blockProvingState.getStartSpongeBlob().clone();
|
|
273
|
+
const blockEndBlobFields = blockProvingState.getBlockEndBlobFields();
|
|
274
|
+
await endSpongeBlob.absorb(blockEndBlobFields);
|
|
275
|
+
blockProvingState.setEndSpongeBlob(endSpongeBlob);
|
|
276
|
+
|
|
277
|
+
// Try to accumulate the out hashes and blobs as far as we can:
|
|
278
|
+
await this.provingState.accumulateCheckpointOutHashes();
|
|
279
|
+
await this.provingState.setBlobAccumulators();
|
|
170
280
|
}
|
|
171
281
|
}
|
|
172
282
|
|
|
@@ -178,28 +288,40 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
178
288
|
[Attributes.BLOCK_TXS_COUNT]: txs.length,
|
|
179
289
|
}))
|
|
180
290
|
public async addTxs(txs: ProcessedTx[]): Promise<void> {
|
|
291
|
+
if (!this.provingState) {
|
|
292
|
+
throw new Error(`Empty epoch proving state. Call startNewEpoch before adding txs.`);
|
|
293
|
+
}
|
|
294
|
+
|
|
181
295
|
if (!txs.length) {
|
|
182
296
|
// To avoid an ugly throw below. If we require an empty block, we can just call setBlockCompleted
|
|
183
297
|
// on a block with no txs. We cannot do that here because we cannot find the blockNumber without any txs.
|
|
184
|
-
logger.warn(`Provided no txs to orchestrator addTxs.`);
|
|
298
|
+
this.logger.warn(`Provided no txs to orchestrator addTxs.`);
|
|
185
299
|
return;
|
|
186
300
|
}
|
|
187
|
-
|
|
188
|
-
const
|
|
301
|
+
|
|
302
|
+
const blockNumber = BlockNumber(txs[0].globalVariables.blockNumber);
|
|
303
|
+
const provingState = this.provingState.getBlockProvingStateByBlockNumber(blockNumber!);
|
|
189
304
|
if (!provingState) {
|
|
190
|
-
throw new Error(`
|
|
305
|
+
throw new Error(`Proving state for block ${blockNumber} not found. Call startNewBlock first.`);
|
|
191
306
|
}
|
|
192
307
|
|
|
193
|
-
if (provingState.totalNumTxs) {
|
|
308
|
+
if (provingState.totalNumTxs !== txs.length) {
|
|
309
|
+
throw new Error(
|
|
310
|
+
`Block ${blockNumber} should be filled with ${provingState.totalNumTxs} txs. Received ${txs.length} txs.`,
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (!provingState.isAcceptingTxs()) {
|
|
194
315
|
throw new Error(`Block ${blockNumber} has been initialized with transactions.`);
|
|
195
316
|
}
|
|
196
317
|
|
|
197
|
-
|
|
198
|
-
|
|
318
|
+
this.logger.info(`Adding ${txs.length} transactions to block ${blockNumber}`);
|
|
319
|
+
|
|
320
|
+
const db = this.dbs.get(blockNumber)!.fork;
|
|
321
|
+
const lastArchive = provingState.lastArchiveTreeSnapshot;
|
|
322
|
+
const newL1ToL2MessageTreeSnapshot = provingState.newL1ToL2MessageTreeSnapshot;
|
|
323
|
+
const spongeBlobState = provingState.getStartSpongeBlob().clone();
|
|
199
324
|
|
|
200
|
-
logger.info(
|
|
201
|
-
`Adding ${txs.length} transactions with ${numBlobFields} blob fields to block ${provingState.blockNumber}`,
|
|
202
|
-
);
|
|
203
325
|
for (const tx of txs) {
|
|
204
326
|
try {
|
|
205
327
|
if (!provingState.verifyState()) {
|
|
@@ -208,15 +330,32 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
208
330
|
|
|
209
331
|
validateTx(tx);
|
|
210
332
|
|
|
211
|
-
logger.
|
|
333
|
+
this.logger.debug(`Received transaction: ${tx.hash}`);
|
|
334
|
+
|
|
335
|
+
const startSpongeBlob = spongeBlobState.clone();
|
|
336
|
+
const [hints, treeSnapshots] = await this.prepareBaseRollupInputs(
|
|
337
|
+
tx,
|
|
338
|
+
lastArchive,
|
|
339
|
+
newL1ToL2MessageTreeSnapshot,
|
|
340
|
+
startSpongeBlob,
|
|
341
|
+
db,
|
|
342
|
+
);
|
|
212
343
|
|
|
213
|
-
|
|
214
|
-
|
|
344
|
+
if (!provingState.verifyState()) {
|
|
345
|
+
throw new Error(`Unable to add transaction, preparing base inputs failed`);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
await spongeBlobState.absorb(tx.txEffect.toBlobFields());
|
|
349
|
+
|
|
350
|
+
const txProvingState = new TxProvingState(tx, hints, treeSnapshots, this.proverId.toField());
|
|
215
351
|
const txIndex = provingState.addNewTx(txProvingState);
|
|
216
|
-
this.getOrEnqueueTube(provingState, txIndex);
|
|
217
352
|
if (txProvingState.requireAvmProof) {
|
|
218
|
-
|
|
353
|
+
this.getOrEnqueueChonkVerifier(provingState, txIndex);
|
|
354
|
+
this.logger.debug(`Enqueueing public VM for tx ${txIndex}`);
|
|
219
355
|
this.enqueueVM(provingState, txIndex);
|
|
356
|
+
} else {
|
|
357
|
+
this.logger.debug(`Enqueueing base rollup for private-only tx ${txIndex}`);
|
|
358
|
+
this.enqueueBaseRollup(provingState, txIndex);
|
|
220
359
|
}
|
|
221
360
|
} catch (err: any) {
|
|
222
361
|
throw new Error(`Error adding transaction ${tx.hash.toString()} to block ${blockNumber}: ${err.message}`, {
|
|
@@ -224,122 +363,163 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
224
363
|
});
|
|
225
364
|
}
|
|
226
365
|
}
|
|
366
|
+
|
|
367
|
+
const endState = await db.getStateReference();
|
|
368
|
+
provingState.setEndState(endState);
|
|
369
|
+
|
|
370
|
+
const blockEndBlobFields = provingState.getBlockEndBlobFields();
|
|
371
|
+
await spongeBlobState.absorb(blockEndBlobFields);
|
|
372
|
+
|
|
373
|
+
provingState.setEndSpongeBlob(spongeBlobState);
|
|
374
|
+
|
|
375
|
+
// Txs have been added to the block. Now try to accumulate the out hashes and blobs as far as we can:
|
|
376
|
+
await this.provingState.accumulateCheckpointOutHashes();
|
|
377
|
+
await this.provingState.setBlobAccumulators();
|
|
227
378
|
}
|
|
228
379
|
|
|
229
380
|
/**
|
|
230
|
-
* Kickstarts
|
|
231
|
-
* Note that if the
|
|
381
|
+
* Kickstarts chonk verifier circuits for the specified txs. These will be used during epoch proving.
|
|
382
|
+
* Note that if the chonk verifier circuits are not started this way, they will be started nontheless after processing.
|
|
232
383
|
*/
|
|
233
|
-
@trackSpan('ProvingOrchestrator.
|
|
234
|
-
public
|
|
384
|
+
@trackSpan('ProvingOrchestrator.startChonkVerifierCircuits')
|
|
385
|
+
public startChonkVerifierCircuits(txs: Tx[]) {
|
|
235
386
|
if (!this.provingState?.verifyState()) {
|
|
236
|
-
throw new Error(`
|
|
387
|
+
throw new Error(`Empty epoch proving state. call startNewEpoch before starting chonk verifier circuits.`);
|
|
237
388
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
const
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
389
|
+
const publicTxs = txs.filter(tx => tx.data.forPublic);
|
|
390
|
+
for (const tx of publicTxs) {
|
|
391
|
+
const txHash = tx.getTxHash().toString();
|
|
392
|
+
const privateInputs = getPublicChonkVerifierPrivateInputsFromTx(tx, this.proverId.toField());
|
|
393
|
+
const tubeProof =
|
|
394
|
+
promiseWithResolvers<
|
|
395
|
+
PublicInputsAndRecursiveProof<
|
|
396
|
+
PublicChonkVerifierPublicInputs,
|
|
397
|
+
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
398
|
+
>
|
|
399
|
+
>();
|
|
400
|
+
this.logger.debug(`Starting chonk verifier circuit for tx ${txHash}`);
|
|
401
|
+
this.doEnqueueChonkVerifier(txHash, privateInputs, proof => {
|
|
402
|
+
tubeProof.resolve(proof);
|
|
403
|
+
});
|
|
404
|
+
this.provingState.cachedChonkVerifierProofs.set(txHash, tubeProof.promise);
|
|
245
405
|
}
|
|
406
|
+
return Promise.resolve();
|
|
246
407
|
}
|
|
247
408
|
|
|
248
409
|
/**
|
|
249
410
|
* Marks the block as completed.
|
|
250
411
|
* Computes the block header and updates the archive tree.
|
|
251
412
|
*/
|
|
252
|
-
@trackSpan('ProvingOrchestrator.setBlockCompleted', (blockNumber:
|
|
413
|
+
@trackSpan('ProvingOrchestrator.setBlockCompleted', (blockNumber: BlockNumber) => ({
|
|
253
414
|
[Attributes.BLOCK_NUMBER]: blockNumber,
|
|
254
415
|
}))
|
|
255
|
-
public async setBlockCompleted(blockNumber:
|
|
416
|
+
public async setBlockCompleted(blockNumber: BlockNumber, expectedHeader?: BlockHeader): Promise<BlockHeader> {
|
|
256
417
|
const provingState = this.provingState?.getBlockProvingStateByBlockNumber(blockNumber);
|
|
257
418
|
if (!provingState) {
|
|
258
419
|
throw new Error(`Block proving state for ${blockNumber} not found`);
|
|
259
420
|
}
|
|
260
421
|
|
|
261
|
-
if
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
422
|
+
// Abort with specific error for the block if there's one.
|
|
423
|
+
const error = provingState.getError();
|
|
424
|
+
if (error) {
|
|
425
|
+
throw new Error(`Block proving failed: ${error}`);
|
|
265
426
|
}
|
|
266
427
|
|
|
428
|
+
// Abort if the proving state is not valid due to errors occurred elsewhere.
|
|
267
429
|
if (!provingState.verifyState()) {
|
|
268
|
-
throw new Error(`
|
|
430
|
+
throw new Error(`Invalid proving state when completing block ${blockNumber}.`);
|
|
269
431
|
}
|
|
270
432
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
// If the proofs were faster than the block building, then we need to try the block root rollup again here
|
|
276
|
-
await this.checkAndEnqueueBlockRootRollup(provingState);
|
|
277
|
-
return provingState.block!;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/** Returns the block as built for a given index. */
|
|
281
|
-
public getBlock(index: number): L2Block {
|
|
282
|
-
const block = this.provingState?.blocks[index]?.block;
|
|
283
|
-
if (!block) {
|
|
284
|
-
throw new Error(`Block at index ${index} not available`);
|
|
433
|
+
if (provingState.isAcceptingTxs()) {
|
|
434
|
+
throw new Error(
|
|
435
|
+
`Block ${blockNumber} is still accepting txs. Call setBlockCompleted after all txs have been added.`,
|
|
436
|
+
);
|
|
285
437
|
}
|
|
286
|
-
return block;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
private async buildBlock(provingState: BlockProvingState, expectedHeader?: BlockHeader) {
|
|
290
|
-
// Collect all new nullifiers, commitments, and contracts from all txs in this block to build body
|
|
291
|
-
const txs = provingState.allTxs.map(a => a.processedTx);
|
|
292
438
|
|
|
293
|
-
//
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
// Given we've applied every change from this block, now assemble the block header
|
|
297
|
-
// and update the archive tree, so we're ready to start processing the next block
|
|
298
|
-
const { header, body } = await buildHeaderAndBodyFromTxs(
|
|
299
|
-
txs,
|
|
300
|
-
provingState.globalVariables,
|
|
301
|
-
provingState.newL1ToL2Messages,
|
|
302
|
-
db,
|
|
303
|
-
);
|
|
439
|
+
// Given we've applied every change from this block, now assemble the block header:
|
|
440
|
+
this.logger.verbose(`Block ${blockNumber} completed. Assembling header.`);
|
|
441
|
+
const header = await provingState.buildBlockHeader();
|
|
304
442
|
|
|
305
443
|
if (expectedHeader && !header.equals(expectedHeader)) {
|
|
306
|
-
logger.error(`Block header mismatch: header=${header} expectedHeader=${expectedHeader}`);
|
|
444
|
+
this.logger.error(`Block header mismatch: header=${header} expectedHeader=${expectedHeader}`);
|
|
307
445
|
throw new Error('Block header mismatch');
|
|
308
446
|
}
|
|
309
447
|
|
|
310
|
-
|
|
448
|
+
// Get db for this block
|
|
449
|
+
const db = this.dbs.get(provingState.blockNumber)!.fork;
|
|
450
|
+
|
|
451
|
+
// Update the archive tree, so we're ready to start processing the next block:
|
|
452
|
+
this.logger.verbose(
|
|
311
453
|
`Updating archive tree with block ${provingState.blockNumber} header ${(await header.hash()).toString()}`,
|
|
312
454
|
);
|
|
313
455
|
await db.updateArchive(header);
|
|
314
456
|
|
|
315
|
-
|
|
316
|
-
const newArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
317
|
-
const l2Block = new L2Block(newArchive, header, body);
|
|
318
|
-
|
|
319
|
-
await this.verifyBuiltBlockAgainstSyncedState(l2Block, newArchive);
|
|
457
|
+
await this.verifyBuiltBlockAgainstSyncedState(provingState);
|
|
320
458
|
|
|
321
|
-
|
|
322
|
-
provingState.block = l2Block;
|
|
459
|
+
return header;
|
|
323
460
|
}
|
|
324
461
|
|
|
325
462
|
// Flagged as protected to disable in certain unit tests
|
|
326
|
-
protected async verifyBuiltBlockAgainstSyncedState(
|
|
327
|
-
const
|
|
463
|
+
protected async verifyBuiltBlockAgainstSyncedState(provingState: BlockProvingState) {
|
|
464
|
+
const builtBlockHeader = provingState.getBuiltBlockHeader();
|
|
465
|
+
if (!builtBlockHeader) {
|
|
466
|
+
this.logger.debug('Block header not built yet, skipping header check.');
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
const output = provingState.getBlockRootRollupOutput();
|
|
471
|
+
if (!output) {
|
|
472
|
+
this.logger.debug('Block root rollup proof not built yet, skipping header check.');
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const header = await buildHeaderFromCircuitOutputs(output);
|
|
476
|
+
|
|
477
|
+
if (!(await header.hash()).equals(await builtBlockHeader.hash())) {
|
|
478
|
+
this.logger.error(`Block header mismatch.\nCircuit: ${inspect(header)}\nComputed: ${inspect(builtBlockHeader)}`);
|
|
479
|
+
provingState.reject(`Block header hash mismatch.`);
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// Get db for this block
|
|
484
|
+
const blockNumber = provingState.blockNumber;
|
|
485
|
+
const db = this.dbs.get(blockNumber)!.fork;
|
|
486
|
+
|
|
487
|
+
const newArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
488
|
+
const syncedArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, this.dbProvider.getSnapshot(blockNumber));
|
|
328
489
|
if (!syncedArchive.equals(newArchive)) {
|
|
329
|
-
|
|
330
|
-
`Archive tree mismatch for block ${
|
|
490
|
+
this.logger.error(
|
|
491
|
+
`Archive tree mismatch for block ${blockNumber}: world state synced to ${inspect(
|
|
331
492
|
syncedArchive,
|
|
332
493
|
)} but built ${inspect(newArchive)}`,
|
|
333
494
|
);
|
|
495
|
+
provingState.reject(`Archive tree mismatch.`);
|
|
496
|
+
return;
|
|
334
497
|
}
|
|
498
|
+
|
|
499
|
+
const circuitArchive = output.newArchive;
|
|
500
|
+
if (!newArchive.equals(circuitArchive)) {
|
|
501
|
+
this.logger.error(`New archive mismatch.\nCircuit: ${output.newArchive}\nComputed: ${newArchive}`);
|
|
502
|
+
provingState.reject(`New archive mismatch.`);
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// TODO(palla/prover): This closes the fork only on the happy path. If this epoch orchestrator
|
|
507
|
+
// is aborted and never reaches this point, it will leak the fork. We need to add a global cleanup,
|
|
508
|
+
// but have to make sure it only runs once all operations are completed, otherwise some function here
|
|
509
|
+
// will attempt to access the fork after it was closed.
|
|
510
|
+
void this.cleanupDBFork(blockNumber);
|
|
335
511
|
}
|
|
336
512
|
|
|
337
513
|
/**
|
|
338
|
-
* Cancel any further proving
|
|
514
|
+
* Cancel any further proving.
|
|
515
|
+
* If cancelJobsOnStop is true, aborts all pending jobs with the broker (which marks them as 'Aborted').
|
|
516
|
+
* If cancelJobsOnStop is false (default), jobs remain in the broker queue and can be reused on restart/reorg.
|
|
339
517
|
*/
|
|
340
518
|
public cancel() {
|
|
341
|
-
|
|
342
|
-
controller.
|
|
519
|
+
if (this.cancelJobsOnStop) {
|
|
520
|
+
for (const controller of this.pendingProvingJobs) {
|
|
521
|
+
controller.abort();
|
|
522
|
+
}
|
|
343
523
|
}
|
|
344
524
|
|
|
345
525
|
this.provingState?.cancel();
|
|
@@ -348,9 +528,13 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
348
528
|
/**
|
|
349
529
|
* Returns the proof for the current epoch.
|
|
350
530
|
*/
|
|
351
|
-
public async
|
|
531
|
+
public async finalizeEpoch(): Promise<{
|
|
532
|
+
publicInputs: RootRollupPublicInputs;
|
|
533
|
+
proof: Proof;
|
|
534
|
+
batchedBlobInputs: BatchedBlob;
|
|
535
|
+
}> {
|
|
352
536
|
if (!this.provingState || !this.provingPromise) {
|
|
353
|
-
throw new Error(`Invalid proving state, an epoch must be proven before it can be
|
|
537
|
+
throw new Error(`Invalid proving state, an epoch must be proven before it can be finalized`);
|
|
354
538
|
}
|
|
355
539
|
|
|
356
540
|
const result = await this.provingPromise!;
|
|
@@ -358,6 +542,8 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
358
542
|
throw new Error(`Epoch proving failed: ${result.reason}`);
|
|
359
543
|
}
|
|
360
544
|
|
|
545
|
+
await this.provingState.finalizeBatchedBlob();
|
|
546
|
+
|
|
361
547
|
const epochProofResult = this.provingState.getEpochProofResult();
|
|
362
548
|
|
|
363
549
|
pushTestData('epochProofResult', {
|
|
@@ -368,18 +554,22 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
368
554
|
return epochProofResult;
|
|
369
555
|
}
|
|
370
556
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
557
|
+
private async cleanupDBFork(blockNumber: BlockNumber): Promise<void> {
|
|
558
|
+
this.logger.debug(`Cleaning up world state fork for ${blockNumber}`);
|
|
559
|
+
const fork = this.dbs.get(blockNumber);
|
|
560
|
+
if (!fork) {
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
try {
|
|
565
|
+
if (!fork.cleanupPromise) {
|
|
566
|
+
fork.cleanupPromise = fork.fork.close();
|
|
567
|
+
}
|
|
568
|
+
await fork.cleanupPromise;
|
|
569
|
+
this.dbs.delete(blockNumber);
|
|
570
|
+
} catch (err) {
|
|
571
|
+
this.logger.error(`Error closing db for block ${blockNumber}`, err);
|
|
381
572
|
}
|
|
382
|
-
return txInputs;
|
|
383
573
|
}
|
|
384
574
|
|
|
385
575
|
/**
|
|
@@ -389,12 +579,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
389
579
|
* @param job - The actual job, returns a promise notifying of the job's completion
|
|
390
580
|
*/
|
|
391
581
|
private deferredProving<T>(
|
|
392
|
-
provingState: EpochProvingState |
|
|
582
|
+
provingState: EpochProvingState | CheckpointProvingState | BlockProvingState,
|
|
393
583
|
request: (signal: AbortSignal) => Promise<T>,
|
|
394
584
|
callback: (result: T) => void | Promise<void>,
|
|
395
585
|
) {
|
|
396
|
-
if (!provingState
|
|
397
|
-
logger.debug(`Not enqueuing job, state no longer valid`);
|
|
586
|
+
if (!provingState.verifyState()) {
|
|
587
|
+
this.logger.debug(`Not enqueuing job, state no longer valid`);
|
|
398
588
|
return;
|
|
399
589
|
}
|
|
400
590
|
|
|
@@ -411,8 +601,8 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
411
601
|
}
|
|
412
602
|
|
|
413
603
|
const result = await request(controller.signal);
|
|
414
|
-
if (!provingState
|
|
415
|
-
logger.debug(`State no longer valid, discarding result`);
|
|
604
|
+
if (!provingState.verifyState()) {
|
|
605
|
+
this.logger.debug(`State no longer valid, discarding result`);
|
|
416
606
|
return;
|
|
417
607
|
}
|
|
418
608
|
|
|
@@ -430,7 +620,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
430
620
|
return;
|
|
431
621
|
}
|
|
432
622
|
|
|
433
|
-
logger.error(`Error thrown when proving job`, err);
|
|
623
|
+
this.logger.error(`Error thrown when proving job`, err);
|
|
434
624
|
provingState!.reject(`${err}`);
|
|
435
625
|
} finally {
|
|
436
626
|
const index = this.pendingProvingJobs.indexOf(controller);
|
|
@@ -444,52 +634,59 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
444
634
|
setImmediate(() => void safeJob());
|
|
445
635
|
}
|
|
446
636
|
|
|
447
|
-
private async
|
|
448
|
-
const l1ToL2MessagesPadded = padArrayEnd(
|
|
637
|
+
private async updateL1ToL2MessageTree(l1ToL2Messages: Fr[], db: MerkleTreeWriteOperations) {
|
|
638
|
+
const l1ToL2MessagesPadded = padArrayEnd<Fr, number>(
|
|
449
639
|
l1ToL2Messages,
|
|
450
640
|
Fr.ZERO,
|
|
451
641
|
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
452
642
|
'Too many L1 to L2 messages',
|
|
453
643
|
);
|
|
454
|
-
const baseParityInputs = times(NUM_BASE_PARITY_PER_ROOT_PARITY, i =>
|
|
455
|
-
BaseParityInputs.fromSlice(l1ToL2MessagesPadded, i, getVKTreeRoot()),
|
|
456
|
-
);
|
|
457
644
|
|
|
458
|
-
const
|
|
645
|
+
const lastL1ToL2MessageTreeSnapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db);
|
|
646
|
+
const lastL1ToL2MessageSubtreeRootSiblingPath = assertLength(
|
|
459
647
|
await getSubtreeSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, L1_TO_L2_MSG_SUBTREE_HEIGHT, db),
|
|
460
|
-
|
|
648
|
+
L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
|
|
461
649
|
);
|
|
462
650
|
|
|
463
651
|
// Update the local trees to include the new l1 to l2 messages
|
|
464
652
|
await db.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPadded);
|
|
465
|
-
|
|
653
|
+
|
|
654
|
+
const newL1ToL2MessageTreeSnapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db);
|
|
655
|
+
const newL1ToL2MessageSubtreeRootSiblingPath = assertLength(
|
|
656
|
+
await getSubtreeSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, L1_TO_L2_MSG_SUBTREE_HEIGHT, db),
|
|
657
|
+
L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
|
|
658
|
+
);
|
|
466
659
|
|
|
467
660
|
return {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
661
|
+
lastL1ToL2MessageTreeSnapshot,
|
|
662
|
+
lastL1ToL2MessageSubtreeRootSiblingPath,
|
|
663
|
+
newL1ToL2MessageTreeSnapshot,
|
|
664
|
+
newL1ToL2MessageSubtreeRootSiblingPath,
|
|
471
665
|
};
|
|
472
666
|
}
|
|
473
667
|
|
|
474
668
|
// Updates the merkle trees for a transaction. The first enqueued job for a transaction
|
|
475
|
-
@trackSpan('ProvingOrchestrator.prepareBaseRollupInputs',
|
|
669
|
+
@trackSpan('ProvingOrchestrator.prepareBaseRollupInputs', tx => ({
|
|
476
670
|
[Attributes.TX_HASH]: tx.hash.toString(),
|
|
477
671
|
}))
|
|
478
672
|
private async prepareBaseRollupInputs(
|
|
479
|
-
provingState: BlockProvingState,
|
|
480
673
|
tx: ProcessedTx,
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
const db = this.dbs.get(provingState.blockNumber)!;
|
|
488
|
-
|
|
674
|
+
lastArchive: AppendOnlyTreeSnapshot,
|
|
675
|
+
newL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot,
|
|
676
|
+
startSpongeBlob: SpongeBlob,
|
|
677
|
+
db: MerkleTreeWriteOperations,
|
|
678
|
+
): Promise<[BaseRollupHints, TreeSnapshots]> {
|
|
489
679
|
// We build the base rollup inputs using a mock proof and verification key.
|
|
490
|
-
// These will be overwritten later once we have proven the
|
|
680
|
+
// These will be overwritten later once we have proven the chonk verifier circuit and any public kernels
|
|
491
681
|
const [ms, hints] = await elapsed(
|
|
492
|
-
|
|
682
|
+
insertSideEffectsAndBuildBaseRollupHints(
|
|
683
|
+
tx,
|
|
684
|
+
lastArchive,
|
|
685
|
+
newL1ToL2MessageTreeSnapshot,
|
|
686
|
+
startSpongeBlob,
|
|
687
|
+
this.proverId.toField(),
|
|
688
|
+
db,
|
|
689
|
+
),
|
|
493
690
|
);
|
|
494
691
|
|
|
495
692
|
this.metrics.recordBaseRollupInputs(ms);
|
|
@@ -501,10 +698,6 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
501
698
|
);
|
|
502
699
|
const treeSnapshots: TreeSnapshots = new Map((await Promise.all(promises)).map(obj => [obj.key, obj.value]));
|
|
503
700
|
|
|
504
|
-
if (!provingState.verifyState()) {
|
|
505
|
-
logger.debug(`Discarding proving job, state no longer valid`);
|
|
506
|
-
return;
|
|
507
|
-
}
|
|
508
701
|
return [hints, treeSnapshots];
|
|
509
702
|
}
|
|
510
703
|
|
|
@@ -512,7 +705,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
512
705
|
// Executes the next level of merge if all inputs are available
|
|
513
706
|
private enqueueBaseRollup(provingState: BlockProvingState, txIndex: number) {
|
|
514
707
|
if (!provingState.verifyState()) {
|
|
515
|
-
logger.debug('Not running base rollup, state invalid');
|
|
708
|
+
this.logger.debug('Not running base rollup, state invalid');
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
if (!provingState.tryStartProvingBase(txIndex)) {
|
|
713
|
+
this.logger.debug(`Base rollup for tx ${txIndex} already started.`);
|
|
516
714
|
return;
|
|
517
715
|
}
|
|
518
716
|
|
|
@@ -520,77 +718,88 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
520
718
|
const { processedTx } = txProvingState;
|
|
521
719
|
const { rollupType, inputs } = txProvingState.getBaseRollupTypeAndInputs();
|
|
522
720
|
|
|
523
|
-
logger.debug(`Enqueuing deferred proving base rollup for ${processedTx.hash.toString()}`);
|
|
721
|
+
this.logger.debug(`Enqueuing deferred proving base rollup for ${processedTx.hash.toString()}`);
|
|
524
722
|
|
|
525
723
|
this.deferredProving(
|
|
526
724
|
provingState,
|
|
527
725
|
wrapCallbackInSpan(
|
|
528
726
|
this.tracer,
|
|
529
727
|
`ProvingOrchestrator.prover.${
|
|
530
|
-
inputs instanceof
|
|
728
|
+
inputs instanceof PrivateTxBaseRollupPrivateInputs
|
|
729
|
+
? 'getPrivateTxBaseRollupProof'
|
|
730
|
+
: 'getPublicTxBaseRollupProof'
|
|
531
731
|
}`,
|
|
532
732
|
{
|
|
533
733
|
[Attributes.TX_HASH]: processedTx.hash.toString(),
|
|
534
|
-
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
535
734
|
[Attributes.PROTOCOL_CIRCUIT_NAME]: rollupType,
|
|
536
735
|
},
|
|
537
736
|
signal => {
|
|
538
|
-
if (inputs instanceof
|
|
539
|
-
return this.prover.
|
|
737
|
+
if (inputs instanceof PrivateTxBaseRollupPrivateInputs) {
|
|
738
|
+
return this.prover.getPrivateTxBaseRollupProof(inputs, signal, provingState.epochNumber);
|
|
540
739
|
} else {
|
|
541
|
-
return this.prover.
|
|
740
|
+
return this.prover.getPublicTxBaseRollupProof(inputs, signal, provingState.epochNumber);
|
|
542
741
|
}
|
|
543
742
|
},
|
|
544
743
|
),
|
|
545
|
-
|
|
546
|
-
logger.debug(`Completed proof for ${rollupType} for tx ${processedTx.hash.toString()}`);
|
|
547
|
-
validatePartialState(result.inputs.
|
|
744
|
+
result => {
|
|
745
|
+
this.logger.debug(`Completed proof for ${rollupType} for tx ${processedTx.hash.toString()}`);
|
|
746
|
+
validatePartialState(result.inputs.endTreeSnapshots, txProvingState.treeSnapshots);
|
|
548
747
|
const leafLocation = provingState.setBaseRollupProof(txIndex, result);
|
|
549
748
|
if (provingState.totalNumTxs === 1) {
|
|
550
|
-
|
|
749
|
+
this.checkAndEnqueueBlockRootRollup(provingState);
|
|
551
750
|
} else {
|
|
552
|
-
|
|
751
|
+
this.checkAndEnqueueNextMergeRollup(provingState, leafLocation);
|
|
553
752
|
}
|
|
554
753
|
},
|
|
555
754
|
);
|
|
556
755
|
}
|
|
557
756
|
|
|
558
|
-
// Enqueues the
|
|
559
|
-
// Once completed, will enqueue the
|
|
560
|
-
private
|
|
757
|
+
// Enqueues the public chonk verifier circuit for a given transaction index, or reuses the one already enqueued.
|
|
758
|
+
// Once completed, will enqueue the the public tx base rollup.
|
|
759
|
+
private getOrEnqueueChonkVerifier(provingState: BlockProvingState, txIndex: number) {
|
|
561
760
|
if (!provingState.verifyState()) {
|
|
562
|
-
logger.debug('Not running
|
|
761
|
+
this.logger.debug('Not running chonk verifier circuit, state invalid');
|
|
563
762
|
return;
|
|
564
763
|
}
|
|
565
764
|
|
|
566
765
|
const txProvingState = provingState.getTxProvingState(txIndex);
|
|
567
766
|
const txHash = txProvingState.processedTx.hash.toString();
|
|
568
|
-
|
|
569
|
-
const handleResult = (
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
767
|
+
NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH;
|
|
768
|
+
const handleResult = (
|
|
769
|
+
result: PublicInputsAndRecursiveProof<
|
|
770
|
+
PublicChonkVerifierPublicInputs,
|
|
771
|
+
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
772
|
+
>,
|
|
773
|
+
) => {
|
|
774
|
+
this.logger.debug(`Got chonk verifier proof for tx index: ${txIndex}`, { txHash });
|
|
775
|
+
txProvingState.setPublicChonkVerifierProof(result);
|
|
776
|
+
this.provingState?.cachedChonkVerifierProofs.delete(txHash);
|
|
777
|
+
this.checkAndEnqueueBaseRollup(provingState, txIndex);
|
|
574
778
|
};
|
|
575
779
|
|
|
576
|
-
if (this.provingState?.
|
|
577
|
-
logger.debug(`
|
|
578
|
-
void this.provingState!.
|
|
780
|
+
if (this.provingState?.cachedChonkVerifierProofs.has(txHash)) {
|
|
781
|
+
this.logger.debug(`Chonk verifier proof already enqueued for tx index: ${txIndex}`, { txHash });
|
|
782
|
+
void this.provingState!.cachedChonkVerifierProofs.get(txHash)!.then(handleResult);
|
|
579
783
|
return;
|
|
580
784
|
}
|
|
581
785
|
|
|
582
|
-
logger.debug(`Enqueuing
|
|
583
|
-
this.
|
|
786
|
+
this.logger.debug(`Enqueuing chonk verifier circuit for tx index: ${txIndex}`);
|
|
787
|
+
this.doEnqueueChonkVerifier(txHash, txProvingState.getPublicChonkVerifierPrivateInputs(), handleResult);
|
|
584
788
|
}
|
|
585
789
|
|
|
586
|
-
private
|
|
790
|
+
private doEnqueueChonkVerifier(
|
|
587
791
|
txHash: string,
|
|
588
|
-
inputs:
|
|
589
|
-
handler: (
|
|
792
|
+
inputs: PublicChonkVerifierPrivateInputs,
|
|
793
|
+
handler: (
|
|
794
|
+
result: PublicInputsAndRecursiveProof<
|
|
795
|
+
PublicChonkVerifierPublicInputs,
|
|
796
|
+
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
797
|
+
>,
|
|
798
|
+
) => void,
|
|
590
799
|
provingState: EpochProvingState | BlockProvingState = this.provingState!,
|
|
591
800
|
) {
|
|
592
|
-
if (!provingState
|
|
593
|
-
logger.debug('Not running
|
|
801
|
+
if (!provingState.verifyState()) {
|
|
802
|
+
this.logger.debug('Not running chonk verifier circuit, state invalid');
|
|
594
803
|
return;
|
|
595
804
|
}
|
|
596
805
|
|
|
@@ -598,13 +807,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
598
807
|
provingState,
|
|
599
808
|
wrapCallbackInSpan(
|
|
600
809
|
this.tracer,
|
|
601
|
-
'ProvingOrchestrator.prover.
|
|
810
|
+
'ProvingOrchestrator.prover.getPublicChonkVerifierProof',
|
|
602
811
|
{
|
|
603
812
|
[Attributes.TX_HASH]: txHash,
|
|
604
|
-
[Attributes.
|
|
605
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'tube-circuit' satisfies CircuitName,
|
|
813
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'chonk-verifier-public' satisfies CircuitName,
|
|
606
814
|
},
|
|
607
|
-
signal => this.prover.
|
|
815
|
+
signal => this.prover.getPublicChonkVerifierProof(inputs, signal, provingState.epochNumber),
|
|
608
816
|
),
|
|
609
817
|
handler,
|
|
610
818
|
);
|
|
@@ -614,7 +822,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
614
822
|
// Enqueues the next level of merge if all inputs are available
|
|
615
823
|
private enqueueMergeRollup(provingState: BlockProvingState, location: TreeNodeLocation) {
|
|
616
824
|
if (!provingState.verifyState()) {
|
|
617
|
-
logger.debug('Not running merge rollup. State no longer valid.');
|
|
825
|
+
this.logger.debug('Not running merge rollup. State no longer valid.');
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
if (!provingState.tryStartProvingMerge(location)) {
|
|
830
|
+
this.logger.debug('Merge rollup already started.');
|
|
618
831
|
return;
|
|
619
832
|
}
|
|
620
833
|
|
|
@@ -624,34 +837,34 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
624
837
|
provingState,
|
|
625
838
|
wrapCallbackInSpan(
|
|
626
839
|
this.tracer,
|
|
627
|
-
'ProvingOrchestrator.prover.
|
|
840
|
+
'ProvingOrchestrator.prover.getTxMergeRollupProof',
|
|
628
841
|
{
|
|
629
|
-
[Attributes.
|
|
630
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'merge-rollup' satisfies CircuitName,
|
|
842
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'rollup-tx-merge' satisfies CircuitName,
|
|
631
843
|
},
|
|
632
|
-
signal => this.prover.
|
|
844
|
+
signal => this.prover.getTxMergeRollupProof(inputs, signal, provingState.epochNumber),
|
|
633
845
|
),
|
|
634
|
-
|
|
846
|
+
result => {
|
|
635
847
|
provingState.setMergeRollupProof(location, result);
|
|
636
|
-
|
|
848
|
+
this.checkAndEnqueueNextMergeRollup(provingState, location);
|
|
637
849
|
},
|
|
638
850
|
);
|
|
639
851
|
}
|
|
640
852
|
|
|
641
853
|
// Executes the block root rollup circuit
|
|
642
|
-
private
|
|
854
|
+
private enqueueBlockRootRollup(provingState: BlockProvingState) {
|
|
643
855
|
if (!provingState.verifyState()) {
|
|
644
|
-
logger.debug('Not running block root rollup, state no longer valid');
|
|
856
|
+
this.logger.debug('Not running block root rollup, state no longer valid');
|
|
645
857
|
return;
|
|
646
858
|
}
|
|
647
859
|
|
|
648
|
-
provingState.
|
|
860
|
+
if (!provingState.tryStartProvingBlockRoot()) {
|
|
861
|
+
this.logger.debug('Block root rollup already started.');
|
|
862
|
+
return;
|
|
863
|
+
}
|
|
649
864
|
|
|
650
|
-
const { rollupType, inputs } =
|
|
865
|
+
const { rollupType, inputs } = provingState.getBlockRootRollupTypeAndInputs();
|
|
651
866
|
|
|
652
|
-
logger.debug(
|
|
653
|
-
`Enqueuing ${rollupType} for block ${provingState.blockNumber} with ${provingState.newL1ToL2Messages.length} l1 to l2 msgs.`,
|
|
654
|
-
);
|
|
867
|
+
this.logger.debug(`Enqueuing ${rollupType} for block ${provingState.blockNumber}.`);
|
|
655
868
|
|
|
656
869
|
this.deferredProving(
|
|
657
870
|
provingState,
|
|
@@ -659,64 +872,74 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
659
872
|
this.tracer,
|
|
660
873
|
'ProvingOrchestrator.prover.getBlockRootRollupProof',
|
|
661
874
|
{
|
|
662
|
-
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
663
875
|
[Attributes.PROTOCOL_CIRCUIT_NAME]: rollupType,
|
|
664
876
|
},
|
|
665
877
|
signal => {
|
|
666
|
-
if (inputs instanceof
|
|
667
|
-
return this.prover.
|
|
668
|
-
} else if (inputs instanceof
|
|
669
|
-
return this.prover.
|
|
878
|
+
if (inputs instanceof BlockRootFirstRollupPrivateInputs) {
|
|
879
|
+
return this.prover.getBlockRootFirstRollupProof(inputs, signal, provingState.epochNumber);
|
|
880
|
+
} else if (inputs instanceof BlockRootSingleTxFirstRollupPrivateInputs) {
|
|
881
|
+
return this.prover.getBlockRootSingleTxFirstRollupProof(inputs, signal, provingState.epochNumber);
|
|
882
|
+
} else if (inputs instanceof BlockRootEmptyTxFirstRollupPrivateInputs) {
|
|
883
|
+
return this.prover.getBlockRootEmptyTxFirstRollupProof(inputs, signal, provingState.epochNumber);
|
|
884
|
+
} else if (inputs instanceof BlockRootSingleTxRollupPrivateInputs) {
|
|
885
|
+
return this.prover.getBlockRootSingleTxRollupProof(inputs, signal, provingState.epochNumber);
|
|
670
886
|
} else {
|
|
671
887
|
return this.prover.getBlockRootRollupProof(inputs, signal, provingState.epochNumber);
|
|
672
888
|
}
|
|
673
889
|
},
|
|
674
890
|
),
|
|
675
891
|
async result => {
|
|
676
|
-
provingState.
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
`Block header mismatch\nCircuit:${inspect(header)}\nComputed:${inspect(provingState.block!.header)}`,
|
|
681
|
-
);
|
|
682
|
-
provingState.reject(`Block header hash mismatch`);
|
|
683
|
-
}
|
|
892
|
+
this.logger.debug(`Completed ${rollupType} proof for block ${provingState.blockNumber}`);
|
|
893
|
+
|
|
894
|
+
const leafLocation = provingState.setBlockRootRollupProof(result);
|
|
895
|
+
const checkpointProvingState = provingState.parentCheckpoint;
|
|
684
896
|
|
|
685
|
-
|
|
686
|
-
|
|
897
|
+
// If the proofs were slower than the block header building, then we need to try validating the block header hashes here.
|
|
898
|
+
await this.verifyBuiltBlockAgainstSyncedState(provingState);
|
|
687
899
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
if (epochProvingState.totalNumBlocks === 1) {
|
|
691
|
-
await this.enqueueEpochPadding(epochProvingState);
|
|
900
|
+
if (checkpointProvingState.totalNumBlocks === 1) {
|
|
901
|
+
this.checkAndEnqueueCheckpointRootRollup(checkpointProvingState);
|
|
692
902
|
} else {
|
|
693
|
-
this.checkAndEnqueueNextBlockMergeRollup(
|
|
903
|
+
this.checkAndEnqueueNextBlockMergeRollup(checkpointProvingState, leafLocation);
|
|
694
904
|
}
|
|
905
|
+
|
|
906
|
+
// We are finished with the block at this point, ensure the fork is cleaned up
|
|
907
|
+
void this.cleanupDBFork(provingState.blockNumber);
|
|
695
908
|
},
|
|
696
909
|
);
|
|
697
910
|
}
|
|
698
911
|
|
|
699
912
|
// Executes the base parity circuit and stores the intermediate state for the root parity circuit
|
|
700
913
|
// Enqueues the root parity circuit if all inputs are available
|
|
701
|
-
private enqueueBaseParityCircuit(
|
|
914
|
+
private enqueueBaseParityCircuit(
|
|
915
|
+
checkpointProvingState: CheckpointProvingState,
|
|
916
|
+
provingState: BlockProvingState,
|
|
917
|
+
baseParityIndex: number,
|
|
918
|
+
) {
|
|
702
919
|
if (!provingState.verifyState()) {
|
|
703
|
-
logger.debug('Not running base parity. State no longer valid.');
|
|
920
|
+
this.logger.debug('Not running base parity. State no longer valid.');
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
if (!provingState.tryStartProvingBaseParity(baseParityIndex)) {
|
|
925
|
+
this.logger.warn(`Base parity ${baseParityIndex} already started.`);
|
|
704
926
|
return;
|
|
705
927
|
}
|
|
706
928
|
|
|
929
|
+
const inputs = checkpointProvingState.getBaseParityInputs(baseParityIndex);
|
|
930
|
+
|
|
707
931
|
this.deferredProving(
|
|
708
932
|
provingState,
|
|
709
933
|
wrapCallbackInSpan(
|
|
710
934
|
this.tracer,
|
|
711
935
|
'ProvingOrchestrator.prover.getBaseParityProof',
|
|
712
936
|
{
|
|
713
|
-
[Attributes.
|
|
714
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'base-parity' satisfies CircuitName,
|
|
937
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'parity-base' satisfies CircuitName,
|
|
715
938
|
},
|
|
716
939
|
signal => this.prover.getBaseParityProof(inputs, signal, provingState.epochNumber),
|
|
717
940
|
),
|
|
718
941
|
provingOutput => {
|
|
719
|
-
provingState.setBaseParityProof(
|
|
942
|
+
provingState.setBaseParityProof(baseParityIndex, provingOutput);
|
|
720
943
|
this.checkAndEnqueueRootParityCircuit(provingState);
|
|
721
944
|
},
|
|
722
945
|
);
|
|
@@ -734,11 +957,16 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
734
957
|
// Enqueues the root rollup proof if all inputs are available
|
|
735
958
|
private enqueueRootParityCircuit(provingState: BlockProvingState) {
|
|
736
959
|
if (!provingState.verifyState()) {
|
|
737
|
-
logger.debug('Not running root parity. State no longer valid.');
|
|
960
|
+
this.logger.debug('Not running root parity. State no longer valid.');
|
|
738
961
|
return;
|
|
739
962
|
}
|
|
740
963
|
|
|
741
|
-
|
|
964
|
+
if (!provingState.tryStartProvingRootParity()) {
|
|
965
|
+
this.logger.debug('Root parity already started.');
|
|
966
|
+
return;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
const inputs = provingState.getParityRootInputs();
|
|
742
970
|
|
|
743
971
|
this.deferredProving(
|
|
744
972
|
provingState,
|
|
@@ -746,36 +974,38 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
746
974
|
this.tracer,
|
|
747
975
|
'ProvingOrchestrator.prover.getRootParityProof',
|
|
748
976
|
{
|
|
749
|
-
[Attributes.
|
|
750
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'root-parity' satisfies CircuitName,
|
|
977
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'parity-root' satisfies CircuitName,
|
|
751
978
|
},
|
|
752
979
|
signal => this.prover.getRootParityProof(inputs, signal, provingState.epochNumber),
|
|
753
980
|
),
|
|
754
|
-
|
|
981
|
+
result => {
|
|
755
982
|
provingState.setRootParityProof(result);
|
|
756
|
-
|
|
983
|
+
this.checkAndEnqueueBlockRootRollup(provingState);
|
|
757
984
|
},
|
|
758
985
|
);
|
|
759
986
|
}
|
|
760
987
|
|
|
761
988
|
// Executes the block merge rollup circuit and stored the output as intermediate state for the parent merge/block root circuit
|
|
762
989
|
// Enqueues the next level of merge if all inputs are available
|
|
763
|
-
private enqueueBlockMergeRollup(provingState:
|
|
990
|
+
private enqueueBlockMergeRollup(provingState: CheckpointProvingState, location: TreeNodeLocation) {
|
|
764
991
|
if (!provingState.verifyState()) {
|
|
765
|
-
logger.debug('Not running block merge rollup. State no longer valid.');
|
|
992
|
+
this.logger.debug('Not running block merge rollup. State no longer valid.');
|
|
766
993
|
return;
|
|
767
994
|
}
|
|
768
995
|
|
|
769
|
-
|
|
996
|
+
if (!provingState.tryStartProvingBlockMerge(location)) {
|
|
997
|
+
this.logger.debug('Block merge rollup already started.');
|
|
998
|
+
return;
|
|
999
|
+
}
|
|
770
1000
|
|
|
1001
|
+
const inputs = provingState.getBlockMergeRollupInputs(location);
|
|
771
1002
|
this.deferredProving(
|
|
772
1003
|
provingState,
|
|
773
1004
|
wrapCallbackInSpan(
|
|
774
1005
|
this.tracer,
|
|
775
1006
|
'ProvingOrchestrator.prover.getBlockMergeRollupProof',
|
|
776
1007
|
{
|
|
777
|
-
[Attributes.
|
|
778
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'block-merge-rollup' satisfies CircuitName,
|
|
1008
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'rollup-block-merge' satisfies CircuitName,
|
|
779
1009
|
},
|
|
780
1010
|
signal => this.prover.getBlockMergeRollupProof(inputs, signal, provingState.epochNumber),
|
|
781
1011
|
),
|
|
@@ -786,30 +1016,125 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
786
1016
|
);
|
|
787
1017
|
}
|
|
788
1018
|
|
|
789
|
-
private
|
|
1019
|
+
private enqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
|
|
1020
|
+
if (!provingState.verifyState()) {
|
|
1021
|
+
this.logger.debug('Not running checkpoint root rollup. State no longer valid.');
|
|
1022
|
+
return;
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
if (!provingState.tryStartProvingCheckpointRoot()) {
|
|
1026
|
+
this.logger.debug('Checkpoint root rollup already started.');
|
|
1027
|
+
return;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
const rollupType = provingState.getCheckpointRootRollupType();
|
|
1031
|
+
|
|
1032
|
+
this.logger.debug(`Enqueuing ${rollupType} for checkpoint ${provingState.index}.`);
|
|
1033
|
+
|
|
1034
|
+
const inputs = provingState.getCheckpointRootRollupInputs();
|
|
1035
|
+
|
|
1036
|
+
this.deferredProving(
|
|
1037
|
+
provingState,
|
|
1038
|
+
wrapCallbackInSpan(
|
|
1039
|
+
this.tracer,
|
|
1040
|
+
'ProvingOrchestrator.prover.getCheckpointRootRollupProof',
|
|
1041
|
+
{
|
|
1042
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: rollupType,
|
|
1043
|
+
},
|
|
1044
|
+
signal => {
|
|
1045
|
+
if (inputs instanceof CheckpointRootSingleBlockRollupPrivateInputs) {
|
|
1046
|
+
return this.prover.getCheckpointRootSingleBlockRollupProof(inputs, signal, provingState.epochNumber);
|
|
1047
|
+
} else {
|
|
1048
|
+
return this.prover.getCheckpointRootRollupProof(inputs, signal, provingState.epochNumber);
|
|
1049
|
+
}
|
|
1050
|
+
},
|
|
1051
|
+
),
|
|
1052
|
+
result => {
|
|
1053
|
+
const computedEndBlobAccumulatorState = provingState.getEndBlobAccumulator()!.toBlobAccumulator();
|
|
1054
|
+
const circuitEndBlobAccumulatorState = result.inputs.endBlobAccumulator;
|
|
1055
|
+
if (!circuitEndBlobAccumulatorState.equals(computedEndBlobAccumulatorState)) {
|
|
1056
|
+
this.logger.error(
|
|
1057
|
+
`Blob accumulator state mismatch.\nCircuit: ${inspect(circuitEndBlobAccumulatorState)}\nComputed: ${inspect(
|
|
1058
|
+
computedEndBlobAccumulatorState,
|
|
1059
|
+
)}`,
|
|
1060
|
+
);
|
|
1061
|
+
provingState.reject(`Blob accumulator state mismatch.`);
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
this.logger.debug(`Completed ${rollupType} proof for checkpoint ${provingState.index}.`);
|
|
1066
|
+
|
|
1067
|
+
const leafLocation = provingState.setCheckpointRootRollupProof(result);
|
|
1068
|
+
const epochProvingState = provingState.parentEpoch;
|
|
1069
|
+
|
|
1070
|
+
if (epochProvingState.totalNumCheckpoints === 1) {
|
|
1071
|
+
this.enqueueEpochPadding(epochProvingState);
|
|
1072
|
+
} else {
|
|
1073
|
+
this.checkAndEnqueueNextCheckpointMergeRollup(epochProvingState, leafLocation);
|
|
1074
|
+
}
|
|
1075
|
+
},
|
|
1076
|
+
);
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
private enqueueCheckpointMergeRollup(provingState: EpochProvingState, location: TreeNodeLocation) {
|
|
790
1080
|
if (!provingState.verifyState()) {
|
|
791
|
-
logger.debug('Not running
|
|
1081
|
+
this.logger.debug('Not running checkpoint merge rollup. State no longer valid.');
|
|
792
1082
|
return;
|
|
793
1083
|
}
|
|
794
1084
|
|
|
795
|
-
|
|
1085
|
+
if (!provingState.tryStartProvingCheckpointMerge(location)) {
|
|
1086
|
+
this.logger.debug('Checkpoint merge rollup already started.');
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
796
1089
|
|
|
797
|
-
const inputs =
|
|
1090
|
+
const inputs = provingState.getCheckpointMergeRollupInputs(location);
|
|
798
1091
|
|
|
799
1092
|
this.deferredProving(
|
|
800
1093
|
provingState,
|
|
801
1094
|
wrapCallbackInSpan(
|
|
802
1095
|
this.tracer,
|
|
803
|
-
'ProvingOrchestrator.prover.
|
|
1096
|
+
'ProvingOrchestrator.prover.getCheckpointMergeRollupProof',
|
|
804
1097
|
{
|
|
805
|
-
[Attributes.
|
|
806
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'empty-block-root-rollup' satisfies CircuitName,
|
|
1098
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'rollup-checkpoint-merge' satisfies CircuitName,
|
|
807
1099
|
},
|
|
808
|
-
signal => this.prover.
|
|
1100
|
+
signal => this.prover.getCheckpointMergeRollupProof(inputs, signal, provingState.epochNumber),
|
|
809
1101
|
),
|
|
810
1102
|
result => {
|
|
811
|
-
logger.debug('Completed proof for
|
|
812
|
-
provingState.
|
|
1103
|
+
this.logger.debug('Completed proof for checkpoint merge rollup.');
|
|
1104
|
+
provingState.setCheckpointMergeRollupProof(location, result);
|
|
1105
|
+
this.checkAndEnqueueNextCheckpointMergeRollup(provingState, location);
|
|
1106
|
+
},
|
|
1107
|
+
);
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
private enqueueEpochPadding(provingState: EpochProvingState) {
|
|
1111
|
+
if (!provingState.verifyState()) {
|
|
1112
|
+
this.logger.debug('Not running epoch padding. State no longer valid.');
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
if (!provingState.tryStartProvingPaddingCheckpoint()) {
|
|
1117
|
+
this.logger.debug('Padding checkpoint already started.');
|
|
1118
|
+
return;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
this.logger.debug('Padding epoch proof with a padding block root proof.');
|
|
1122
|
+
|
|
1123
|
+
const inputs = provingState.getPaddingCheckpointInputs();
|
|
1124
|
+
|
|
1125
|
+
this.deferredProving(
|
|
1126
|
+
provingState,
|
|
1127
|
+
wrapCallbackInSpan(
|
|
1128
|
+
this.tracer,
|
|
1129
|
+
'ProvingOrchestrator.prover.getCheckpointPaddingRollupProof',
|
|
1130
|
+
{
|
|
1131
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'rollup-checkpoint-padding' satisfies CircuitName,
|
|
1132
|
+
},
|
|
1133
|
+
signal => this.prover.getCheckpointPaddingRollupProof(inputs, signal, provingState.epochNumber),
|
|
1134
|
+
),
|
|
1135
|
+
result => {
|
|
1136
|
+
this.logger.debug('Completed proof for padding checkpoint.');
|
|
1137
|
+
provingState.setCheckpointPaddingProof(result);
|
|
813
1138
|
this.checkAndEnqueueRootRollup(provingState);
|
|
814
1139
|
},
|
|
815
1140
|
);
|
|
@@ -818,13 +1143,13 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
818
1143
|
// Executes the root rollup circuit
|
|
819
1144
|
private enqueueRootRollup(provingState: EpochProvingState) {
|
|
820
1145
|
if (!provingState.verifyState()) {
|
|
821
|
-
logger.debug('Not running root rollup, state no longer valid');
|
|
1146
|
+
this.logger.debug('Not running root rollup, state no longer valid');
|
|
822
1147
|
return;
|
|
823
1148
|
}
|
|
824
1149
|
|
|
825
|
-
logger.debug(`Preparing root rollup`);
|
|
1150
|
+
this.logger.debug(`Preparing root rollup`);
|
|
826
1151
|
|
|
827
|
-
const inputs = provingState.getRootRollupInputs(
|
|
1152
|
+
const inputs = provingState.getRootRollupInputs();
|
|
828
1153
|
|
|
829
1154
|
this.deferredProving(
|
|
830
1155
|
provingState,
|
|
@@ -832,59 +1157,63 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
832
1157
|
this.tracer,
|
|
833
1158
|
'ProvingOrchestrator.prover.getRootRollupProof',
|
|
834
1159
|
{
|
|
835
|
-
[Attributes.
|
|
836
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'root-rollup' satisfies CircuitName,
|
|
1160
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'rollup-root' satisfies CircuitName,
|
|
837
1161
|
},
|
|
838
1162
|
signal => this.prover.getRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
839
1163
|
),
|
|
840
1164
|
result => {
|
|
841
|
-
logger.verbose(`Orchestrator completed root rollup for epoch ${provingState.epochNumber}`);
|
|
1165
|
+
this.logger.verbose(`Orchestrator completed root rollup for epoch ${provingState.epochNumber}`);
|
|
842
1166
|
provingState.setRootRollupProof(result);
|
|
843
1167
|
provingState.resolve({ status: 'success' });
|
|
844
1168
|
},
|
|
845
1169
|
);
|
|
846
1170
|
}
|
|
847
1171
|
|
|
848
|
-
private
|
|
1172
|
+
private checkAndEnqueueNextMergeRollup(provingState: BlockProvingState, currentLocation: TreeNodeLocation) {
|
|
849
1173
|
if (!provingState.isReadyForMergeRollup(currentLocation)) {
|
|
850
1174
|
return;
|
|
851
1175
|
}
|
|
852
1176
|
|
|
853
1177
|
const parentLocation = provingState.getParentLocation(currentLocation);
|
|
854
1178
|
if (parentLocation.level === 0) {
|
|
855
|
-
|
|
1179
|
+
this.checkAndEnqueueBlockRootRollup(provingState);
|
|
856
1180
|
} else {
|
|
857
1181
|
this.enqueueMergeRollup(provingState, parentLocation);
|
|
858
1182
|
}
|
|
859
1183
|
}
|
|
860
1184
|
|
|
861
|
-
private
|
|
1185
|
+
private checkAndEnqueueBlockRootRollup(provingState: BlockProvingState) {
|
|
862
1186
|
if (!provingState.isReadyForBlockRootRollup()) {
|
|
863
|
-
logger.debug('Not ready for root rollup');
|
|
1187
|
+
this.logger.debug('Not ready for block root rollup');
|
|
864
1188
|
return;
|
|
865
1189
|
}
|
|
866
|
-
|
|
867
|
-
|
|
1190
|
+
|
|
1191
|
+
this.enqueueBlockRootRollup(provingState);
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
private checkAndEnqueueNextBlockMergeRollup(provingState: CheckpointProvingState, currentLocation: TreeNodeLocation) {
|
|
1195
|
+
if (!provingState.isReadyForBlockMerge(currentLocation)) {
|
|
868
1196
|
return;
|
|
869
1197
|
}
|
|
870
|
-
const blockNumber = provingState.blockNumber;
|
|
871
1198
|
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
1199
|
+
const parentLocation = provingState.getParentLocation(currentLocation);
|
|
1200
|
+
if (parentLocation.level === 0) {
|
|
1201
|
+
this.checkAndEnqueueCheckpointRootRollup(provingState);
|
|
1202
|
+
} else {
|
|
1203
|
+
this.enqueueBlockMergeRollup(provingState, parentLocation);
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
private checkAndEnqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
|
|
1208
|
+
if (!provingState.isReadyForCheckpointRoot()) {
|
|
1209
|
+
return;
|
|
1210
|
+
}
|
|
882
1211
|
|
|
883
|
-
|
|
1212
|
+
this.enqueueCheckpointRootRollup(provingState);
|
|
884
1213
|
}
|
|
885
1214
|
|
|
886
|
-
private
|
|
887
|
-
if (!provingState.
|
|
1215
|
+
private checkAndEnqueueNextCheckpointMergeRollup(provingState: EpochProvingState, currentLocation: TreeNodeLocation) {
|
|
1216
|
+
if (!provingState.isReadyForCheckpointMerge(currentLocation)) {
|
|
888
1217
|
return;
|
|
889
1218
|
}
|
|
890
1219
|
|
|
@@ -892,13 +1221,13 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
892
1221
|
if (parentLocation.level === 0) {
|
|
893
1222
|
this.checkAndEnqueueRootRollup(provingState);
|
|
894
1223
|
} else {
|
|
895
|
-
this.
|
|
1224
|
+
this.enqueueCheckpointMergeRollup(provingState, parentLocation);
|
|
896
1225
|
}
|
|
897
1226
|
}
|
|
898
1227
|
|
|
899
1228
|
private checkAndEnqueueRootRollup(provingState: EpochProvingState) {
|
|
900
1229
|
if (!provingState.isReadyForRootRollup()) {
|
|
901
|
-
logger.debug('Not ready for root rollup');
|
|
1230
|
+
this.logger.debug('Not ready for root rollup');
|
|
902
1231
|
return;
|
|
903
1232
|
}
|
|
904
1233
|
|
|
@@ -913,14 +1242,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
913
1242
|
*/
|
|
914
1243
|
private enqueueVM(provingState: BlockProvingState, txIndex: number) {
|
|
915
1244
|
if (!provingState.verifyState()) {
|
|
916
|
-
logger.debug(`Not running VM circuit as state is no longer valid`);
|
|
1245
|
+
this.logger.debug(`Not running VM circuit as state is no longer valid`);
|
|
917
1246
|
return;
|
|
918
1247
|
}
|
|
919
1248
|
|
|
920
1249
|
const txProvingState = provingState.getTxProvingState(txIndex);
|
|
921
1250
|
|
|
922
|
-
// This function tries to do AVM proving. If there is a failure, it fakes the proof unless AVM_PROVING_STRICT is defined.
|
|
923
|
-
// Nothing downstream depends on the AVM proof yet. So having this mode lets us incrementally build the AVM circuit.
|
|
924
1251
|
const doAvmProving = wrapCallbackInSpan(
|
|
925
1252
|
this.tracer,
|
|
926
1253
|
'ProvingOrchestrator.prover.getAvmProof',
|
|
@@ -929,42 +1256,25 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
929
1256
|
},
|
|
930
1257
|
async (signal: AbortSignal) => {
|
|
931
1258
|
const inputs = txProvingState.getAvmInputs();
|
|
932
|
-
|
|
933
|
-
return await this.prover.getAvmProof(inputs, signal, provingState.epochNumber);
|
|
934
|
-
} catch (err) {
|
|
935
|
-
if (process.env.AVM_PROVING_STRICT) {
|
|
936
|
-
logger.error(`Error thrown when proving AVM circuit with AVM_PROVING_STRICT on`, err);
|
|
937
|
-
throw err;
|
|
938
|
-
} else {
|
|
939
|
-
logger.warn(
|
|
940
|
-
`Error thrown when proving AVM circuit but AVM_PROVING_STRICT is off. Faking AVM proof and carrying on. ${inspect(
|
|
941
|
-
err,
|
|
942
|
-
)}.`,
|
|
943
|
-
);
|
|
944
|
-
return {
|
|
945
|
-
proof: makeEmptyRecursiveProof(AVM_PROOF_LENGTH_IN_FIELDS),
|
|
946
|
-
verificationKey: VerificationKeyData.makeFake(AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS),
|
|
947
|
-
};
|
|
948
|
-
}
|
|
949
|
-
}
|
|
1259
|
+
return await this.prover.getAvmProof(inputs, signal, provingState.epochNumber);
|
|
950
1260
|
},
|
|
951
1261
|
);
|
|
952
1262
|
|
|
953
|
-
this.deferredProving(provingState, doAvmProving,
|
|
954
|
-
logger.debug(`Proven VM for tx index: ${txIndex}`);
|
|
955
|
-
txProvingState.setAvmProof(
|
|
956
|
-
this.
|
|
1263
|
+
this.deferredProving(provingState, doAvmProving, proof => {
|
|
1264
|
+
this.logger.debug(`Proven VM for tx index: ${txIndex}`);
|
|
1265
|
+
txProvingState.setAvmProof(proof);
|
|
1266
|
+
this.checkAndEnqueueBaseRollup(provingState, txIndex);
|
|
957
1267
|
});
|
|
958
1268
|
}
|
|
959
1269
|
|
|
960
|
-
private
|
|
1270
|
+
private checkAndEnqueueBaseRollup(provingState: BlockProvingState, txIndex: number) {
|
|
961
1271
|
const txProvingState = provingState.getTxProvingState(txIndex);
|
|
962
1272
|
if (!txProvingState.ready()) {
|
|
963
1273
|
return;
|
|
964
1274
|
}
|
|
965
1275
|
|
|
966
|
-
// We must have completed all proving (
|
|
967
|
-
logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`);
|
|
1276
|
+
// We must have completed all proving (chonk verifier proof and (if required) vm proof are generated), we now move to the base rollup.
|
|
1277
|
+
this.logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`);
|
|
968
1278
|
|
|
969
1279
|
this.enqueueBaseRollup(provingState, txIndex);
|
|
970
1280
|
}
|