@aztec/prover-client 0.0.1-commit.b655e406 → 0.0.1-commit.b9865e97
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 +17 -3
- 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 +231 -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 +31 -46
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +133 -123
- 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 +29 -9
- package/dest/orchestrator/checkpoint-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/checkpoint-proving-state.js +62 -21
- package/dest/orchestrator/checkpoint-sub-tree-orchestrator.d.ts +107 -0
- package/dest/orchestrator/checkpoint-sub-tree-orchestrator.d.ts.map +1 -0
- package/dest/orchestrator/checkpoint-sub-tree-orchestrator.js +151 -0
- package/dest/orchestrator/epoch-proving-context.d.ts +51 -0
- package/dest/orchestrator/epoch-proving-context.d.ts.map +1 -0
- package/dest/orchestrator/epoch-proving-context.js +81 -0
- 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 +4 -1
- package/dest/orchestrator/index.d.ts.map +1 -1
- package/dest/orchestrator/index.js +3 -0
- package/dest/orchestrator/orchestrator.d.ts +37 -32
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +568 -303
- 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/proving-scheduler.d.ts +72 -0
- package/dest/orchestrator/proving-scheduler.d.ts.map +1 -0
- package/dest/orchestrator/proving-scheduler.js +117 -0
- package/dest/orchestrator/top-tree-orchestrator.d.ts +83 -0
- package/dest/orchestrator/top-tree-orchestrator.d.ts.map +1 -0
- package/dest/orchestrator/top-tree-orchestrator.js +182 -0
- package/dest/orchestrator/top-tree-proving-scheduler.d.ts +62 -0
- package/dest/orchestrator/top-tree-proving-scheduler.d.ts.map +1 -0
- package/dest/orchestrator/top-tree-proving-scheduler.js +73 -0
- package/dest/orchestrator/top-tree-proving-state.d.ts +61 -0
- package/dest/orchestrator/top-tree-proving-state.d.ts.map +1 -0
- package/dest/orchestrator/top-tree-proving-state.js +185 -0
- 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 +66 -7
- package/dest/prover-client/prover-client.d.ts.map +1 -1
- package/dest/prover-client/prover-client.js +64 -11
- 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 +21 -33
- package/dest/proving_broker/config.d.ts +14 -62
- 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 +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 +2 -1
- package/dest/proving_broker/index.d.ts.map +1 -1
- package/dest/proving_broker/index.js +1 -0
- 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 +8 -5
- package/dest/proving_broker/proving_broker.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker.js +74 -22
- 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 +394 -5
- 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 +9 -5
- package/dest/proving_broker/rpc.d.ts.map +1 -1
- package/dest/proving_broker/rpc.js +87 -23
- 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 +23 -22
- package/src/config.ts +19 -3
- package/src/light/index.ts +1 -0
- package/src/light/lightweight_checkpoint_builder.ts +320 -0
- package/src/mocks/fixtures.ts +9 -31
- package/src/mocks/test_context.ts +170 -185
- 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 +89 -26
- package/src/orchestrator/checkpoint-sub-tree-orchestrator.ts +271 -0
- package/src/orchestrator/epoch-proving-context.ts +101 -0
- package/src/orchestrator/epoch-proving-state.ts +67 -15
- package/src/orchestrator/index.ts +8 -0
- package/src/orchestrator/orchestrator.ts +193 -354
- package/src/orchestrator/orchestrator_metrics.ts +2 -25
- package/src/orchestrator/proving-scheduler.ts +156 -0
- package/src/orchestrator/top-tree-orchestrator.ts +314 -0
- package/src/orchestrator/top-tree-proving-scheduler.ts +154 -0
- package/src/orchestrator/top-tree-proving-state.ts +220 -0
- package/src/orchestrator/tx-proving-state.ts +10 -27
- package/src/prover-client/factory.ts +6 -2
- package/src/prover-client/prover-client.ts +157 -24
- package/src/prover-client/server-epoch-prover.ts +6 -7
- package/src/proving_broker/broker_prover_facade.ts +46 -55
- package/src/proving_broker/config.ts +33 -3
- package/src/proving_broker/fixtures.ts +8 -3
- package/src/proving_broker/index.ts +1 -0
- 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 +70 -17
- package/src/proving_broker/proving_broker_database/memory.ts +2 -1
- package/src/proving_broker/proving_broker_database/persisted.ts +22 -7
- 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 +46 -20
- 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,18 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BatchedBlobAccumulator,
|
|
3
|
+
type FinalBlobBatchingChallenges,
|
|
4
|
+
SpongeBlob,
|
|
5
|
+
encodeCheckpointBlobDataFromBlocks,
|
|
6
|
+
} from '@aztec/blob-lib';
|
|
2
7
|
import {
|
|
3
8
|
type ARCHIVE_HEIGHT,
|
|
4
|
-
|
|
9
|
+
BLOBS_PER_CHECKPOINT,
|
|
5
10
|
FIELDS_PER_BLOB,
|
|
6
11
|
type L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
|
|
7
12
|
type NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
|
|
8
13
|
NUM_MSGS_PER_BASE_PARITY,
|
|
14
|
+
OUT_HASH_TREE_HEIGHT,
|
|
9
15
|
} from '@aztec/constants';
|
|
16
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
10
17
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
11
|
-
import { BLS12Point
|
|
18
|
+
import { BLS12Point } from '@aztec/foundation/curves/bls12';
|
|
19
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
12
20
|
import type { Tuple } from '@aztec/foundation/serialize';
|
|
13
21
|
import { type TreeNodeLocation, UnbalancedTreeStore } from '@aztec/foundation/trees';
|
|
14
|
-
import { getCheckpointBlobFields } from '@aztec/stdlib/checkpoint';
|
|
15
22
|
import type { PublicInputsAndRecursiveProof } from '@aztec/stdlib/interfaces/server';
|
|
23
|
+
import { computeCheckpointOutHash } from '@aztec/stdlib/messaging';
|
|
16
24
|
import { ParityBasePrivateInputs } from '@aztec/stdlib/parity';
|
|
17
25
|
import {
|
|
18
26
|
BlockMergeRollupPrivateInputs,
|
|
@@ -32,6 +40,11 @@ import { accumulateBlobs, buildBlobHints, toProofData } from './block-building-h
|
|
|
32
40
|
import { BlockProvingState, type ProofState } from './block-proving-state.js';
|
|
33
41
|
import type { EpochProvingState } from './epoch-proving-state.js';
|
|
34
42
|
|
|
43
|
+
type OutHashHint = {
|
|
44
|
+
treeSnapshot: AppendOnlyTreeSnapshot;
|
|
45
|
+
siblingPath: Tuple<Fr, typeof OUT_HASH_TREE_HEIGHT>;
|
|
46
|
+
};
|
|
47
|
+
|
|
35
48
|
export class CheckpointProvingState {
|
|
36
49
|
private blockProofs: UnbalancedTreeStore<
|
|
37
50
|
ProofState<BlockRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
|
|
@@ -40,17 +53,21 @@ export class CheckpointProvingState {
|
|
|
40
53
|
| ProofState<CheckpointRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
|
|
41
54
|
| undefined;
|
|
42
55
|
private blocks: (BlockProvingState | undefined)[] = [];
|
|
56
|
+
private previousOutHashHint: OutHashHint | undefined;
|
|
57
|
+
private outHash: Fr | undefined;
|
|
58
|
+
// The snapshot and sibling path after the checkpoint's out hash is inserted.
|
|
59
|
+
// Stored here to be retrieved for the next checkpoint when it's added.
|
|
60
|
+
private newOutHashHint: OutHashHint | undefined;
|
|
43
61
|
private startBlobAccumulator: BatchedBlobAccumulator | undefined;
|
|
44
62
|
private endBlobAccumulator: BatchedBlobAccumulator | undefined;
|
|
45
63
|
private blobFields: Fr[] | undefined;
|
|
46
64
|
private error: string | undefined;
|
|
47
|
-
public readonly firstBlockNumber:
|
|
65
|
+
public readonly firstBlockNumber: BlockNumber;
|
|
48
66
|
|
|
49
67
|
constructor(
|
|
50
68
|
public readonly index: number,
|
|
51
69
|
public readonly constants: CheckpointConstantData,
|
|
52
70
|
public readonly totalNumBlocks: number,
|
|
53
|
-
private readonly totalNumBlobFields: number,
|
|
54
71
|
private readonly finalBlobBatchingChallenges: FinalBlobBatchingChallenges,
|
|
55
72
|
private readonly headerOfLastBlockInPreviousCheckpoint: BlockHeader,
|
|
56
73
|
private readonly lastArchiveSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>,
|
|
@@ -68,24 +85,24 @@ export class CheckpointProvingState {
|
|
|
68
85
|
typeof L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH
|
|
69
86
|
>,
|
|
70
87
|
public parentEpoch: EpochProvingState,
|
|
71
|
-
private onBlobAccumulatorSet: (checkpoint: CheckpointProvingState) => void
|
|
88
|
+
private onBlobAccumulatorSet: (checkpoint: CheckpointProvingState) => Promise<void>,
|
|
72
89
|
) {
|
|
73
90
|
this.blockProofs = new UnbalancedTreeStore(totalNumBlocks);
|
|
74
|
-
this.firstBlockNumber = headerOfLastBlockInPreviousCheckpoint.globalVariables.blockNumber + 1;
|
|
91
|
+
this.firstBlockNumber = BlockNumber(headerOfLastBlockInPreviousCheckpoint.globalVariables.blockNumber + 1);
|
|
75
92
|
}
|
|
76
93
|
|
|
77
94
|
public get epochNumber(): number {
|
|
78
95
|
return this.parentEpoch.epochNumber;
|
|
79
96
|
}
|
|
80
97
|
|
|
81
|
-
public
|
|
82
|
-
blockNumber:
|
|
98
|
+
public startNewBlock(
|
|
99
|
+
blockNumber: BlockNumber,
|
|
83
100
|
timestamp: UInt64,
|
|
84
101
|
totalNumTxs: number,
|
|
85
102
|
lastArchiveTreeSnapshot: AppendOnlyTreeSnapshot,
|
|
86
103
|
lastArchiveSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>,
|
|
87
|
-
):
|
|
88
|
-
const index = blockNumber - this.firstBlockNumber;
|
|
104
|
+
): BlockProvingState {
|
|
105
|
+
const index = Number(blockNumber) - Number(this.firstBlockNumber);
|
|
89
106
|
if (index >= this.totalNumBlocks) {
|
|
90
107
|
throw new Error(`Unable to start a new block at index ${index}. Expected at most ${this.totalNumBlocks} blocks.`);
|
|
91
108
|
}
|
|
@@ -98,8 +115,7 @@ export class CheckpointProvingState {
|
|
|
98
115
|
const lastL1ToL2MessageSubtreeRootSiblingPath =
|
|
99
116
|
index === 0 ? this.lastL1ToL2MessageSubtreeRootSiblingPath : this.newL1ToL2MessageSubtreeRootSiblingPath;
|
|
100
117
|
|
|
101
|
-
const startSpongeBlob =
|
|
102
|
-
index === 0 ? await SpongeBlob.init(this.totalNumBlobFields) : this.blocks[index - 1]?.getEndSpongeBlob();
|
|
118
|
+
const startSpongeBlob = index === 0 ? SpongeBlob.init() : this.blocks[index - 1]?.getEndSpongeBlob();
|
|
103
119
|
if (!startSpongeBlob) {
|
|
104
120
|
throw new Error(
|
|
105
121
|
'Cannot start a new block before the trees have progressed from the tx effects in the previous block.',
|
|
@@ -188,19 +204,48 @@ export class CheckpointProvingState {
|
|
|
188
204
|
Fr.ZERO,
|
|
189
205
|
NUM_MSGS_PER_BASE_PARITY,
|
|
190
206
|
);
|
|
191
|
-
return new ParityBasePrivateInputs(messages, this.constants.vkTreeRoot);
|
|
207
|
+
return new ParityBasePrivateInputs(messages, this.constants.vkTreeRoot, this.constants.proverId);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
public setOutHashHint(hint: OutHashHint) {
|
|
211
|
+
this.previousOutHashHint = hint;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
public getOutHashHint() {
|
|
215
|
+
return this.previousOutHashHint;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
public accumulateBlockOutHashes() {
|
|
219
|
+
if (this.isAcceptingBlocks() || this.blocks.some(b => !b?.hasEndState())) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (!this.outHash) {
|
|
224
|
+
const messagesPerBlock = this.blocks.map(b => b!.getTxEffects().map(tx => tx.l2ToL1Msgs));
|
|
225
|
+
this.outHash = computeCheckpointOutHash(messagesPerBlock);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return this.outHash;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
public setOutHashHintForNextCheckpoint(hint: OutHashHint) {
|
|
232
|
+
this.newOutHashHint = hint;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
public getOutHashHintForNextCheckpoint() {
|
|
236
|
+
return this.newOutHashHint;
|
|
192
237
|
}
|
|
193
238
|
|
|
194
239
|
public async accumulateBlobs(startBlobAccumulator: BatchedBlobAccumulator) {
|
|
195
|
-
if (this.isAcceptingBlocks() || this.blocks.some(b => b
|
|
240
|
+
if (this.isAcceptingBlocks() || this.blocks.some(b => !b?.hasEndState())) {
|
|
196
241
|
return;
|
|
197
242
|
}
|
|
198
243
|
|
|
199
|
-
this.blobFields =
|
|
200
|
-
this.endBlobAccumulator = await accumulateBlobs(this.blobFields
|
|
244
|
+
this.blobFields = encodeCheckpointBlobDataFromBlocks(this.blocks.map(b => b!.getBlockBlobData()));
|
|
245
|
+
this.endBlobAccumulator = await accumulateBlobs(this.blobFields!, startBlobAccumulator);
|
|
201
246
|
this.startBlobAccumulator = startBlobAccumulator;
|
|
202
247
|
|
|
203
|
-
this.onBlobAccumulatorSet(this);
|
|
248
|
+
await this.onBlobAccumulatorSet(this);
|
|
204
249
|
|
|
205
250
|
return this.endBlobAccumulator;
|
|
206
251
|
}
|
|
@@ -226,12 +271,15 @@ export class CheckpointProvingState {
|
|
|
226
271
|
return this.totalNumBlocks === 1 ? 'rollup-checkpoint-root-single-block' : 'rollup-checkpoint-root';
|
|
227
272
|
}
|
|
228
273
|
|
|
229
|
-
public getCheckpointRootRollupInputs() {
|
|
274
|
+
public async getCheckpointRootRollupInputs() {
|
|
230
275
|
const proofs = this.#getChildProofsForRoot();
|
|
231
276
|
const nonEmptyProofs = proofs.filter(p => !!p);
|
|
232
277
|
if (proofs.length !== nonEmptyProofs.length) {
|
|
233
278
|
throw new Error('At least one child is not ready for the checkpoint root rollup.');
|
|
234
279
|
}
|
|
280
|
+
if (!this.previousOutHashHint) {
|
|
281
|
+
throw new Error('Out hash hint is not set.');
|
|
282
|
+
}
|
|
235
283
|
if (!this.startBlobAccumulator) {
|
|
236
284
|
throw new Error('Start blob accumulator is not set.');
|
|
237
285
|
}
|
|
@@ -239,15 +287,17 @@ export class CheckpointProvingState {
|
|
|
239
287
|
// `blobFields` must've been set if `startBlobAccumulator` is set (in `accumulateBlobs`).
|
|
240
288
|
const blobFields = this.blobFields!;
|
|
241
289
|
|
|
242
|
-
const { blobCommitments, blobsHash } = buildBlobHints(blobFields);
|
|
290
|
+
const { blobCommitments, blobsHash } = await buildBlobHints(blobFields);
|
|
243
291
|
|
|
244
292
|
const hints = CheckpointRootRollupHints.from({
|
|
245
293
|
previousBlockHeader: this.headerOfLastBlockInPreviousCheckpoint,
|
|
246
294
|
previousArchiveSiblingPath: this.lastArchiveSiblingPath,
|
|
295
|
+
previousOutHash: this.previousOutHashHint.treeSnapshot,
|
|
296
|
+
newOutHashSiblingPath: this.previousOutHashHint.siblingPath,
|
|
247
297
|
startBlobAccumulator: this.startBlobAccumulator.toBlobAccumulator(),
|
|
248
298
|
finalBlobChallenges: this.finalBlobBatchingChallenges,
|
|
249
|
-
blobFields: padArrayEnd(blobFields, Fr.ZERO, FIELDS_PER_BLOB *
|
|
250
|
-
blobCommitments: padArrayEnd(blobCommitments, BLS12Point.ZERO,
|
|
299
|
+
blobFields: padArrayEnd(blobFields, Fr.ZERO, FIELDS_PER_BLOB * BLOBS_PER_CHECKPOINT),
|
|
300
|
+
blobCommitments: padArrayEnd(blobCommitments, BLS12Point.ZERO, BLOBS_PER_CHECKPOINT),
|
|
251
301
|
blobsHash,
|
|
252
302
|
});
|
|
253
303
|
|
|
@@ -258,8 +308,8 @@ export class CheckpointProvingState {
|
|
|
258
308
|
: new CheckpointRootRollupPrivateInputs([left, right], hints);
|
|
259
309
|
}
|
|
260
310
|
|
|
261
|
-
public getBlockProvingStateByBlockNumber(blockNumber:
|
|
262
|
-
const index = blockNumber - this.firstBlockNumber;
|
|
311
|
+
public getBlockProvingStateByBlockNumber(blockNumber: BlockNumber) {
|
|
312
|
+
const index = Number(blockNumber) - Number(this.firstBlockNumber);
|
|
263
313
|
return this.blocks[index];
|
|
264
314
|
}
|
|
265
315
|
|
|
@@ -269,7 +319,7 @@ export class CheckpointProvingState {
|
|
|
269
319
|
|
|
270
320
|
public isReadyForCheckpointRoot() {
|
|
271
321
|
const allChildProofsReady = this.#getChildProofsForRoot().every(p => !!p);
|
|
272
|
-
return allChildProofsReady && !!this.startBlobAccumulator;
|
|
322
|
+
return allChildProofsReady && !!this.previousOutHashHint && !!this.startBlobAccumulator;
|
|
273
323
|
}
|
|
274
324
|
|
|
275
325
|
public verifyState() {
|
|
@@ -296,4 +346,17 @@ export class CheckpointProvingState {
|
|
|
296
346
|
? [this.blockProofs.getNode(rootLocation)?.provingOutput] // If there's only 1 block, its proof will be stored at the root.
|
|
297
347
|
: this.blockProofs.getChildren(rootLocation).map(c => c?.provingOutput);
|
|
298
348
|
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Returns the block-level proof outputs that feed into the checkpoint root rollup.
|
|
352
|
+
* Used by `CheckpointSubTreeOrchestrator` to surface its sub-tree result.
|
|
353
|
+
*/
|
|
354
|
+
public getSubTreeOutputProofs() {
|
|
355
|
+
return this.#getChildProofsForRoot();
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/** Sibling path of the archive tree captured before any block in this checkpoint landed. */
|
|
359
|
+
public getLastArchiveSiblingPath() {
|
|
360
|
+
return this.lastArchiveSiblingPath;
|
|
361
|
+
}
|
|
299
362
|
}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { FinalBlobBatchingChallenges } from '@aztec/blob-lib';
|
|
2
|
+
import type { ARCHIVE_HEIGHT, NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH } from '@aztec/constants';
|
|
3
|
+
import type { EpochNumber } from '@aztec/foundation/branded-types';
|
|
4
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
|
+
import type { LoggerBindings } from '@aztec/foundation/log';
|
|
6
|
+
import { type PromiseWithResolvers, promiseWithResolvers } from '@aztec/foundation/promise';
|
|
7
|
+
import type { Tuple } from '@aztec/foundation/serialize';
|
|
8
|
+
import type { EthAddress } from '@aztec/stdlib/block';
|
|
9
|
+
import type {
|
|
10
|
+
ForkMerkleTreeOperations,
|
|
11
|
+
PublicInputsAndRecursiveProof,
|
|
12
|
+
ReadonlyWorldStateAccess,
|
|
13
|
+
ServerCircuitProver,
|
|
14
|
+
} from '@aztec/stdlib/interfaces/server';
|
|
15
|
+
import type {
|
|
16
|
+
BlockRollupPublicInputs,
|
|
17
|
+
CheckpointConstantData,
|
|
18
|
+
PublicChonkVerifierPublicInputs,
|
|
19
|
+
} from '@aztec/stdlib/rollup';
|
|
20
|
+
import type { BlockHeader, Tx } from '@aztec/stdlib/tx';
|
|
21
|
+
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
22
|
+
|
|
23
|
+
import { getPublicChonkVerifierPrivateInputsFromTx } from './block-building-helpers.js';
|
|
24
|
+
import type { BlockProvingState } from './block-proving-state.js';
|
|
25
|
+
import type { CheckpointProvingState } from './checkpoint-proving-state.js';
|
|
26
|
+
import type { EpochProvingContext } from './epoch-proving-context.js';
|
|
27
|
+
import { ProvingOrchestrator } from './orchestrator.js';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Result of proving a single checkpoint's block-level sub-tree.
|
|
31
|
+
*
|
|
32
|
+
* Contains the final block-rollup proof outputs that feed the checkpoint root rollup,
|
|
33
|
+
* plus the archive sibling path captured before any block in the checkpoint landed
|
|
34
|
+
* (the top-tree needs this to assemble the checkpoint root rollup hints).
|
|
35
|
+
*/
|
|
36
|
+
export type SubTreeResult = {
|
|
37
|
+
blockProofOutputs: PublicInputsAndRecursiveProof<
|
|
38
|
+
BlockRollupPublicInputs,
|
|
39
|
+
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
40
|
+
>[];
|
|
41
|
+
previousArchiveSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Orchestrates block-level proving for a single checkpoint, stopping at the boundary
|
|
46
|
+
* where checkpoint root rollup would otherwise begin.
|
|
47
|
+
*
|
|
48
|
+
* Reuses every circuit driver in `ProvingOrchestrator` (chonk verifier, base, merge,
|
|
49
|
+
* block-root, parity, block-merge) but overrides the gating method that escalates to
|
|
50
|
+
* checkpoint root rollup. Instead of escalating, the orchestrator resolves
|
|
51
|
+
* `getSubTreeResult()` once every block-level proof in the checkpoint's tree is ready.
|
|
52
|
+
*
|
|
53
|
+
* Wiring: a single-checkpoint epoch is created in the constructor (epoch number sourced
|
|
54
|
+
* from the supplied `EpochProvingContext`). The canonical way to obtain a fully-started
|
|
55
|
+
* sub-tree is the `start` static factory, which also drives the single internal
|
|
56
|
+
* `startNewCheckpoint(0, ...)` call. The sub-tree never calls `finalizeEpochStructure`;
|
|
57
|
+
* the override of `checkAndEnqueueCheckpointRootRollup` resolves `getSubTreeResult` once
|
|
58
|
+
* block-level proving completes.
|
|
59
|
+
*/
|
|
60
|
+
export class CheckpointSubTreeOrchestrator extends ProvingOrchestrator {
|
|
61
|
+
private readonly subTreeResult: PromiseWithResolvers<SubTreeResult>;
|
|
62
|
+
|
|
63
|
+
constructor(
|
|
64
|
+
dbProvider: ReadonlyWorldStateAccess & ForkMerkleTreeOperations,
|
|
65
|
+
prover: ServerCircuitProver,
|
|
66
|
+
proverId: EthAddress,
|
|
67
|
+
/**
|
|
68
|
+
* Per-epoch shared chonk-verifier proof cache. Every chonk-verifier proof started
|
|
69
|
+
* by this sub-tree lives on the context and survives the sub-tree's cancellation,
|
|
70
|
+
* so a tx whose original checkpoint is reorged out and re-appears in a replacement
|
|
71
|
+
* checkpoint reuses the cached proof. The context's `epochNumber` is the epoch
|
|
72
|
+
* this sub-tree proves into.
|
|
73
|
+
*/
|
|
74
|
+
private readonly epochContext: EpochProvingContext,
|
|
75
|
+
cancelJobsOnStop: boolean = false,
|
|
76
|
+
enqueueConcurrency: number,
|
|
77
|
+
telemetryClient: TelemetryClient = getTelemetryClient(),
|
|
78
|
+
bindings?: LoggerBindings,
|
|
79
|
+
) {
|
|
80
|
+
super(dbProvider, prover, proverId, cancelJobsOnStop, enqueueConcurrency, telemetryClient, bindings);
|
|
81
|
+
|
|
82
|
+
// Single-checkpoint mini-epoch by construction. The total/challenges supplied to
|
|
83
|
+
// `super.startNewEpoch` are never read, because the sub-tree overrides
|
|
84
|
+
// `checkAndEnqueueCheckpointRootRollup` to short-circuit before the parent's
|
|
85
|
+
// checkpoint-root / finalize machinery would consume them.
|
|
86
|
+
super.startNewEpoch(epochContext.epochNumber, 1, FinalBlobBatchingChallenges.empty());
|
|
87
|
+
|
|
88
|
+
this.subTreeResult = promiseWithResolvers<SubTreeResult>();
|
|
89
|
+
// Mark the rejection branch as observed so a `cancel()` or proving failure does not
|
|
90
|
+
// surface an unhandled rejection when no consumer awaits getSubTreeResult().
|
|
91
|
+
this.subTreeResult.promise.catch(() => {});
|
|
92
|
+
|
|
93
|
+
// If the parent's proving state ever rejects, surface the failure on the sub-tree promise.
|
|
94
|
+
void this.provingPromise!.then(result => {
|
|
95
|
+
if (result.status === 'failure') {
|
|
96
|
+
this.subTreeResult.reject(new Error(result.reason));
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Constructs and starts a sub-tree for a single checkpoint. The returned sub-tree
|
|
103
|
+
* has had its single internal `startNewCheckpoint(0, ...)` driven; callers proceed
|
|
104
|
+
* directly to per-block `startNewBlock` / `addTxs` / `setBlockCompleted`.
|
|
105
|
+
*
|
|
106
|
+
* If the internal `startNewCheckpoint` rejects, the partially-constructed sub-tree
|
|
107
|
+
* is stopped before the error propagates, so no broker resources leak.
|
|
108
|
+
*/
|
|
109
|
+
public static async start(
|
|
110
|
+
dbProvider: ReadonlyWorldStateAccess & ForkMerkleTreeOperations,
|
|
111
|
+
prover: ServerCircuitProver,
|
|
112
|
+
proverId: EthAddress,
|
|
113
|
+
epochContext: EpochProvingContext,
|
|
114
|
+
cancelJobsOnStop: boolean,
|
|
115
|
+
enqueueConcurrency: number,
|
|
116
|
+
checkpointConstants: CheckpointConstantData,
|
|
117
|
+
l1ToL2Messages: Fr[],
|
|
118
|
+
totalNumBlocks: number,
|
|
119
|
+
headerOfLastBlockInPreviousCheckpoint: BlockHeader,
|
|
120
|
+
telemetryClient: TelemetryClient = getTelemetryClient(),
|
|
121
|
+
bindings?: LoggerBindings,
|
|
122
|
+
): Promise<CheckpointSubTreeOrchestrator> {
|
|
123
|
+
const subTree = new CheckpointSubTreeOrchestrator(
|
|
124
|
+
dbProvider,
|
|
125
|
+
prover,
|
|
126
|
+
proverId,
|
|
127
|
+
epochContext,
|
|
128
|
+
cancelJobsOnStop,
|
|
129
|
+
enqueueConcurrency,
|
|
130
|
+
telemetryClient,
|
|
131
|
+
bindings,
|
|
132
|
+
);
|
|
133
|
+
try {
|
|
134
|
+
await ProvingOrchestrator.prototype.startNewCheckpoint.call(
|
|
135
|
+
subTree,
|
|
136
|
+
0,
|
|
137
|
+
checkpointConstants,
|
|
138
|
+
l1ToL2Messages,
|
|
139
|
+
totalNumBlocks,
|
|
140
|
+
headerOfLastBlockInPreviousCheckpoint,
|
|
141
|
+
);
|
|
142
|
+
return subTree;
|
|
143
|
+
} catch (err) {
|
|
144
|
+
await subTree.stop().catch(() => {});
|
|
145
|
+
throw err;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** Returns a promise that resolves when block-level proving completes for the checkpoint. */
|
|
150
|
+
public getSubTreeResult(): Promise<SubTreeResult> {
|
|
151
|
+
return this.subTreeResult.promise;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* The epoch is started in the constructor.
|
|
156
|
+
*/
|
|
157
|
+
public override startNewEpoch(
|
|
158
|
+
_epochNumber: EpochNumber,
|
|
159
|
+
_totalNumCheckpoints: number,
|
|
160
|
+
_finalBlobBatchingChallenges: FinalBlobBatchingChallenges,
|
|
161
|
+
): void {
|
|
162
|
+
throw new Error('CheckpointSubTreeOrchestrator starts its epoch in the constructor; do not call startNewEpoch.');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* The single internal checkpoint is started by the `start` factory
|
|
167
|
+
*/
|
|
168
|
+
public override startNewCheckpoint(
|
|
169
|
+
_checkpointIndex: number,
|
|
170
|
+
_constants: CheckpointConstantData,
|
|
171
|
+
_l1ToL2Messages: Fr[],
|
|
172
|
+
_totalNumBlocks: number,
|
|
173
|
+
_headerOfLastBlockInPreviousCheckpoint: BlockHeader,
|
|
174
|
+
): Promise<void> {
|
|
175
|
+
return Promise.reject(
|
|
176
|
+
new Error(
|
|
177
|
+
'CheckpointSubTreeOrchestrator drives its single checkpoint in `start`; do not call startNewCheckpoint.',
|
|
178
|
+
),
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Returns the archive sibling path captured at the internal `startNewCheckpoint`.
|
|
184
|
+
* Available synchronously once `start` has resolved, before block-level proving
|
|
185
|
+
* completes. The top-tree consumer uses this to assemble checkpoint root rollup hints
|
|
186
|
+
* up-front so checkpoint root proofs can pipeline against in-flight sub-tree proving.
|
|
187
|
+
*/
|
|
188
|
+
public getPreviousArchiveSiblingPath(): Tuple<Fr, typeof ARCHIVE_HEIGHT> {
|
|
189
|
+
const checkpoint = this.provingState!.getCheckpointProvingState(0);
|
|
190
|
+
if (!checkpoint) {
|
|
191
|
+
throw new Error('Checkpoint not started; call CheckpointSubTreeOrchestrator.start first.');
|
|
192
|
+
}
|
|
193
|
+
return checkpoint.getLastArchiveSiblingPath();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Override the checkpoint-root boundary: instead of escalating to checkpoint root,
|
|
198
|
+
* resolve the sub-tree promise with the block-level proof outputs once they're all ready.
|
|
199
|
+
*/
|
|
200
|
+
// eslint-disable-next-line require-await
|
|
201
|
+
protected override async checkAndEnqueueCheckpointRootRollup(provingState: CheckpointProvingState): Promise<void> {
|
|
202
|
+
const proofs = provingState.getSubTreeOutputProofs();
|
|
203
|
+
const nonEmpty = proofs.filter((p): p is NonNullable<typeof p> => !!p);
|
|
204
|
+
if (proofs.length !== nonEmpty.length) {
|
|
205
|
+
// Block merge tree not fully resolved yet — will be retried as more block proofs land.
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
this.subTreeResult.resolve({
|
|
210
|
+
blockProofOutputs: nonEmpty,
|
|
211
|
+
previousArchiveSiblingPath: provingState.getLastArchiveSiblingPath(),
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Kickstart chonk-verifier circuits via the shared `EpochProvingContext`. The context
|
|
217
|
+
* owns the broker job lifecycle, so the proof survives this sub-tree's `cancel()` —
|
|
218
|
+
* a tx that ends up in a replacement checkpoint after a reorg can pick the cached
|
|
219
|
+
* promise up and skip re-proving.
|
|
220
|
+
*/
|
|
221
|
+
public override startChonkVerifierCircuits(txs: Tx[]): Promise<void> {
|
|
222
|
+
if (!this.provingState?.verifyState()) {
|
|
223
|
+
return Promise.reject(new Error('Sub-tree proving state is not active.'));
|
|
224
|
+
}
|
|
225
|
+
const publicTxs = txs.filter(tx => tx.data.forPublic);
|
|
226
|
+
for (const tx of publicTxs) {
|
|
227
|
+
const txHash = tx.getTxHash().toString();
|
|
228
|
+
const inputs = getPublicChonkVerifierPrivateInputsFromTx(tx, this.getProverId().toField());
|
|
229
|
+
// Fire and forget — getOrEnqueueChonkVerifier later picks up the cached promise
|
|
230
|
+
// when the tx is processed inside its block.
|
|
231
|
+
void this.epochContext.enqueue(txHash, inputs);
|
|
232
|
+
}
|
|
233
|
+
return Promise.resolve();
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Route the tx's chonk-verifier dependency through the per-epoch context: read the
|
|
238
|
+
* cached promise (or enqueue if missing), then `.then(handleResult)` to progress to
|
|
239
|
+
* the base rollup once the proof lands.
|
|
240
|
+
*/
|
|
241
|
+
protected override getOrEnqueueChonkVerifier(provingState: BlockProvingState, txIndex: number) {
|
|
242
|
+
if (!provingState.verifyState()) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const txProvingState = provingState.getTxProvingState(txIndex);
|
|
247
|
+
const txHash = txProvingState.processedTx.hash.toString();
|
|
248
|
+
|
|
249
|
+
const handleResult = (
|
|
250
|
+
result: PublicInputsAndRecursiveProof<
|
|
251
|
+
PublicChonkVerifierPublicInputs,
|
|
252
|
+
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
253
|
+
>,
|
|
254
|
+
) => {
|
|
255
|
+
if (!provingState.verifyState()) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
txProvingState.setPublicChonkVerifierProof(result);
|
|
259
|
+
this.checkAndEnqueueBaseRollup(provingState, txIndex);
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
let promise = this.epochContext.getCached(txHash);
|
|
263
|
+
if (!promise) {
|
|
264
|
+
promise = this.epochContext.enqueue(txHash, txProvingState.getPublicChonkVerifierPrivateInputs());
|
|
265
|
+
}
|
|
266
|
+
void promise.then(handleResult).catch(() => {
|
|
267
|
+
// The context self-cleans on rejection; a future call (replacement sub-tree
|
|
268
|
+
// for this tx) will see the miss and re-enqueue. No action needed here.
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH } from '@aztec/constants';
|
|
2
|
+
import type { EpochNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
4
|
+
import type { PublicInputsAndRecursiveProof, ServerCircuitProver } from '@aztec/stdlib/interfaces/server';
|
|
5
|
+
import type { PublicChonkVerifierPrivateInputs, PublicChonkVerifierPublicInputs } from '@aztec/stdlib/rollup';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Result of a chonk-verifier proof, cached per tx hash on `EpochProvingContext`.
|
|
9
|
+
*/
|
|
10
|
+
export type ChonkVerifierProofResult = PublicInputsAndRecursiveProof<
|
|
11
|
+
PublicChonkVerifierPublicInputs,
|
|
12
|
+
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Per-epoch state shared across every `CheckpointSubTreeOrchestrator` constructed for
|
|
17
|
+
* the same epoch. Owns the chonk-verifier proof cache so a tx whose checkpoint is
|
|
18
|
+
* reorged out and re-appears in a replacement checkpoint does not have to re-prove
|
|
19
|
+
* its chonk circuit.
|
|
20
|
+
*
|
|
21
|
+
* The context's chonk-verifier broker jobs are deliberately submitted **outside** the
|
|
22
|
+
* sub-tree's deferred-proving queue. The sub-tree's `cancel()` therefore does not abort
|
|
23
|
+
* them — by design, because their result is tx-scoped, not sub-tree-scoped, and a
|
|
24
|
+
* replacement sub-tree should be able to consume the cached proof.
|
|
25
|
+
*
|
|
26
|
+
* Callers (`EpochProvingJob`, or unit tests) construct one context per epoch and pass
|
|
27
|
+
* it into every sub-tree they create. `stop()` aborts every in-flight chonk job.
|
|
28
|
+
*/
|
|
29
|
+
export class EpochProvingContext {
|
|
30
|
+
private readonly cache = new Map<string, Promise<ChonkVerifierProofResult>>();
|
|
31
|
+
/** Abort controllers for in-flight chonk jobs, keyed by tx hash. */
|
|
32
|
+
private readonly pending = new Map<string, AbortController>();
|
|
33
|
+
private readonly log: Logger;
|
|
34
|
+
private stopped = false;
|
|
35
|
+
|
|
36
|
+
constructor(
|
|
37
|
+
private readonly prover: ServerCircuitProver,
|
|
38
|
+
public readonly epochNumber: EpochNumber,
|
|
39
|
+
bindings?: LoggerBindings,
|
|
40
|
+
) {
|
|
41
|
+
this.log = createLogger('prover-client:epoch-proving-context', bindings);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Returns the cached chonk-verifier proof promise for the given tx hash, or
|
|
46
|
+
* `undefined` if none has been enqueued yet. Non-mutating.
|
|
47
|
+
*/
|
|
48
|
+
public getCached(txHash: string): Promise<ChonkVerifierProofResult> | undefined {
|
|
49
|
+
return this.cache.get(txHash);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Enqueues a chonk-verifier proof for the given tx hash, returning the promise (or
|
|
54
|
+
* the already-cached one if already enqueued). The promise resolves when the broker
|
|
55
|
+
* delivers the result; on rejection (including `stop()`), the cache entry is removed
|
|
56
|
+
* so a subsequent caller can re-enqueue.
|
|
57
|
+
*/
|
|
58
|
+
public enqueue(txHash: string, inputs: PublicChonkVerifierPrivateInputs): Promise<ChonkVerifierProofResult> {
|
|
59
|
+
if (this.stopped) {
|
|
60
|
+
return Promise.reject(new Error('EpochProvingContext is stopped'));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const cached = this.cache.get(txHash);
|
|
64
|
+
if (cached) {
|
|
65
|
+
return cached;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const controller = new AbortController();
|
|
69
|
+
this.pending.set(txHash, controller);
|
|
70
|
+
this.log.debug(`Enqueueing chonk-verifier circuit`, { txHash, epochNumber: this.epochNumber });
|
|
71
|
+
|
|
72
|
+
const promise = this.prover
|
|
73
|
+
.getPublicChonkVerifierProof(inputs, controller.signal, this.epochNumber)
|
|
74
|
+
.finally(() => this.pending.delete(txHash));
|
|
75
|
+
|
|
76
|
+
// Self-clean on rejection so a future caller can re-enqueue. Mark the rejection
|
|
77
|
+
// path as observed to silence unhandled-rejection warnings when no consumer
|
|
78
|
+
// awaits the promise (e.g. when the only `.then` chain belonged to a cancelled
|
|
79
|
+
// sub-tree's tx-proving state).
|
|
80
|
+
promise.catch(err => {
|
|
81
|
+
this.cache.delete(txHash);
|
|
82
|
+
this.log.debug(`Chonk-verifier proof failed; evicted from cache`, { txHash, error: `${err}` });
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
this.cache.set(txHash, promise);
|
|
86
|
+
return promise;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Aborts every in-flight chonk-verifier broker job and clears the cache. Called by
|
|
91
|
+
* the owning `EpochProvingJob` when the job stops.
|
|
92
|
+
*/
|
|
93
|
+
public stop() {
|
|
94
|
+
this.stopped = true;
|
|
95
|
+
for (const controller of this.pending.values()) {
|
|
96
|
+
controller.abort();
|
|
97
|
+
}
|
|
98
|
+
this.pending.clear();
|
|
99
|
+
this.cache.clear();
|
|
100
|
+
}
|
|
101
|
+
}
|