@aztec/prover-node 5.1.0 → 5.2.0-nightly.20260724
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/README.md +95 -34
- package/dest/actions/rerun-epoch-proving-job.d.ts +11 -2
- package/dest/actions/rerun-epoch-proving-job.d.ts.map +1 -1
- package/dest/actions/rerun-epoch-proving-job.js +83 -41
- package/dest/checkpoint-store.d.ts +9 -2
- package/dest/checkpoint-store.d.ts.map +1 -1
- package/dest/checkpoint-store.js +9 -0
- package/dest/job/checkpoint-prover.d.ts +34 -4
- package/dest/job/checkpoint-prover.d.ts.map +1 -1
- package/dest/job/checkpoint-prover.js +41 -8
- package/dest/job/epoch-session.d.ts +14 -2
- package/dest/job/epoch-session.d.ts.map +1 -1
- package/dest/job/epoch-session.js +24 -2
- package/dest/prover-node.d.ts +34 -7
- package/dest/prover-node.d.ts.map +1 -1
- package/dest/prover-node.js +78 -17
- package/dest/session-manager.d.ts +16 -16
- package/dest/session-manager.d.ts.map +1 -1
- package/dest/session-manager.js +62 -62
- package/package.json +23 -23
- package/src/actions/rerun-epoch-proving-job.ts +124 -65
- package/src/checkpoint-store.ts +20 -2
- package/src/job/checkpoint-prover.ts +61 -7
- package/src/job/epoch-session.ts +26 -2
- package/src/prover-node.ts +94 -19
- package/src/session-manager.ts +70 -66
package/README.md
CHANGED
|
@@ -48,10 +48,12 @@ The prover-node splits responsibility between four classes:
|
|
|
48
48
|
|
|
49
49
|
- **`ProverNode`** — owns the long-lived collections, wires the L2BlockStream, and
|
|
50
50
|
translates each chain event into a single method call on the `SessionManager` or
|
|
51
|
-
`ProofPublishingService`. It also performs
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
`ProofPublishingService`. It also performs side effects that don't belong on an
|
|
52
|
+
`EpochSession`: registering new checkpoints with the store per event, and sweeping expired
|
|
53
|
+
epochs out of the cache and the store on a periodic ticker (see below). It uploads post-mortem
|
|
54
|
+
snapshots on failure at two levels: per checkpoint when a `CheckpointProver` fails (its `onFailed`
|
|
55
|
+
callback), and per session when a full session fails on its own account (`onSessionFailed` /
|
|
56
|
+
`EpochSession.hasFailed()`).
|
|
55
57
|
- **`CheckpointStore`** — a registry of `CheckpointProver` instances keyed by
|
|
56
58
|
`(checkpointNumber, slot, archiveRoot)`. Each `CheckpointProver` runs its own sub-tree pipeline
|
|
57
59
|
(tx gather → block processing → block-rollup proofs), starting eagerly the moment a
|
|
@@ -64,8 +66,12 @@ The prover-node splits responsibility between four classes:
|
|
|
64
66
|
translated into a `reconcile(trigger)` call, a single idempotent function that walks
|
|
65
67
|
all `EpochSession`s, cancels any whose canonical content has shifted, re-creates them with
|
|
66
68
|
the new content, and opens fresh full `EpochSession`s for any epoch that has become provable.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
It never builds a session over a **failed** `CheckpointProver` (one whose block proofs rejected —
|
|
70
|
+
a sub-tree fault or a prune-induced fork fault): a session over it could only fail, so the epoch is
|
|
71
|
+
cheaply skipped until a prune/re-add installs a fresh prover in its place, at which point a rebuilt
|
|
72
|
+
session reuses every already-completed sub-proof from the content-addressed broker. Reconcile runs on
|
|
73
|
+
a `SerialQueue` (from `@aztec/foundation/queue`), so two concurrent triggers can never interleave on an
|
|
74
|
+
`await` and race on the `EpochSession` maps.
|
|
69
75
|
- **`ProofPublishingService`** — central owner of L1 proof submission. `EpochSession`s hand
|
|
70
76
|
their top-tree proofs to the service as `PublishCandidate`s; the service serialises
|
|
71
77
|
one publish at a time against a freshly-created `ProverNodePublisher`, gates eligibility
|
|
@@ -150,9 +156,9 @@ stateDiagram-v2
|
|
|
150
156
|
awaiting_root --> publishing_proof: epoch proof ready, submit to L1
|
|
151
157
|
publishing_proof --> completed: publish succeeds
|
|
152
158
|
publishing_proof --> superseded: longer same-epoch candidate wins
|
|
153
|
-
publishing_proof --> failed: L1 submission errored
|
|
154
|
-
awaiting_checkpoints -->
|
|
155
|
-
awaiting_root --> failed: top-tree prove errored
|
|
159
|
+
publishing_proof --> failed: L1 submission errored (provers healthy)
|
|
160
|
+
awaiting_checkpoints --> stopped: a checkpoint prover failed
|
|
161
|
+
awaiting_root --> failed: top-tree prove errored (provers healthy)
|
|
156
162
|
initialized --> timed_out: deadline
|
|
157
163
|
awaiting_checkpoints --> timed_out: deadline (EpochSession or candidate)
|
|
158
164
|
awaiting_root --> timed_out: deadline (EpochSession or candidate)
|
|
@@ -162,9 +168,22 @@ stateDiagram-v2
|
|
|
162
168
|
superseded --> [*]
|
|
163
169
|
cancelled --> [*]
|
|
164
170
|
timed_out --> [*]
|
|
171
|
+
stopped --> [*]
|
|
165
172
|
failed --> [*]
|
|
166
173
|
```
|
|
167
174
|
|
|
175
|
+
A fault settles the `EpochSession` in one of two terminal states:
|
|
176
|
+
|
|
177
|
+
- **`stopped`** — a `CheckpointProver` under the session failed (its block proofs rejected). This may
|
|
178
|
+
be a prune-induced fork fault, so it is *not* a verdict on the epoch and is *not* uploaded. The
|
|
179
|
+
reconciler drops the session and, guarded by `isFailed()`, does not rebuild over the failed prover;
|
|
180
|
+
a prune/re-add installs a fresh prover and the epoch is retried.
|
|
181
|
+
- **`failed`** — the session's own work (top-tree prove or L1 submit) failed while *every* checkpoint
|
|
182
|
+
prover succeeded. Because healthy provers rule out a prune, this is a genuine, race-free failure
|
|
183
|
+
(`EpochSession.hasFailed()`). The reconciler retains such a full session (so the tick does not
|
|
184
|
+
re-prove a deterministically-failing epoch) and uploads a post-mortem exactly once. No prune/fault
|
|
185
|
+
classification is needed — the two states carry it.
|
|
186
|
+
|
|
168
187
|
The non-terminal states track the window between `start()` and the L1 submission:
|
|
169
188
|
|
|
170
189
|
- `awaiting-checkpoints` — a `TopTreeJob` is awaiting each checkpoint's sub-tree result
|
|
@@ -323,44 +342,57 @@ sequenceDiagram
|
|
|
323
342
|
PS->>PS: drain reads proven afresh, re-checks eligibility
|
|
324
343
|
```
|
|
325
344
|
|
|
326
|
-
###
|
|
345
|
+
### Periodic expiry sweep
|
|
327
346
|
|
|
328
347
|
```mermaid
|
|
329
348
|
sequenceDiagram
|
|
330
|
-
participant
|
|
349
|
+
participant T as expiryTicker (RunningPromise)
|
|
331
350
|
participant PN as ProverNode
|
|
351
|
+
participant L2 as L2BlockStream
|
|
332
352
|
participant CC as ChonkCache
|
|
333
353
|
participant CS as CheckpointStore
|
|
334
354
|
|
|
335
|
-
|
|
355
|
+
T->>PN: checkEpochExpiry() (every poll interval)
|
|
336
356
|
PN->>L2: getSyncedL2SlotNumber()
|
|
337
357
|
PN->>PN: latestEpoch = getEpochAtSlot(latestSlot)
|
|
338
358
|
PN->>PN: newlyExpiredUpTo = latestEpoch - (proofSubmissionEpochs + 1)
|
|
339
359
|
loop for each newly-expired epoch
|
|
340
|
-
PN->>L2:
|
|
360
|
+
PN->>L2: getBlocks({epoch, onlyCheckpointed})
|
|
341
361
|
PN->>CC: releaseForBlocks(blocks)
|
|
342
362
|
PN->>CS: reapExpired(epoch)
|
|
343
363
|
end
|
|
344
364
|
```
|
|
345
365
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
`
|
|
352
|
-
|
|
366
|
+
The sweep is driven solely by the `expiryTicker` (a `RunningPromise` armed in `start()`), which
|
|
367
|
+
calls `checkEpochExpiry()` every poll interval whether or not block-stream events arrive. It is
|
|
368
|
+
deliberately **not** run from `handleBlockStreamEvent` — expiry is a background sweep keyed off the
|
|
369
|
+
archiver's synced slot, not part of event processing — and because a `RunningPromise` never overlaps
|
|
370
|
+
its own runs, no two sweeps can race. An epoch `E` is expired once the chain reaches the start of epoch
|
|
371
|
+
`E + proofSubmissionEpochs + 1` — the deadline beyond which an L1 submission for `E` would be rejected.
|
|
372
|
+
Expiry only releases the chonk cache and reaps `E`'s provers.
|
|
373
|
+
A monotonic high-water mark (`lastExpiredEpoch`) makes the sweep cheap: it only
|
|
374
|
+
advances after a sweep completes and never revisits an epoch. It is seeded at `start()` from the last
|
|
375
|
+
fully-proven epoch (`resolveLastFullyProvenEpoch`), so on a restart we never re-sweep epochs that already
|
|
376
|
+
reached L1.
|
|
353
377
|
|
|
354
378
|
### Periodic tick
|
|
355
379
|
|
|
356
380
|
`SessionManager.start()` arms a `RunningPromise` that fires
|
|
357
381
|
`reconcile({ kind: 'tick' })` every `tickIntervalMs`. The tick picks up epochs that
|
|
358
382
|
became complete by time alone (no fresh checkpoint event) and advances to the
|
|
359
|
-
next unproven epoch once the previous one lands on L1.
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
383
|
+
next unproven epoch once the previous one lands on L1. The tick is not gated by any per-epoch
|
|
384
|
+
bookkeeping; two things keep it from re-proving a doomed epoch:
|
|
385
|
+
|
|
386
|
+
- `openFullSessionIfReady` refuses to build a session when any `CheckpointProver` in the set has
|
|
387
|
+
**failed** (`isFailed()`). So a prover fault (possibly a prune) skips the epoch cheaply each tick —
|
|
388
|
+
no session, no proving — until a prune/re-add installs a fresh prover.
|
|
389
|
+
- A session that failed on its own account (`hasFailed()` — top-tree/submit failed with every prover
|
|
390
|
+
healthy) is **retained** by `recreateInvalidSessions` rather than deleted, so the tick's
|
|
391
|
+
`fullSessions.has(epoch)` check skips it. It is replaced only when its canonical content changes (a
|
|
392
|
+
re-add), so a deterministically-failing epoch is not re-proved every tick.
|
|
393
|
+
|
|
394
|
+
Transient blockers (max-pending-jobs reached, archiver still indexing) create no session and no failed
|
|
395
|
+
prover, so the next tick simply tries again.
|
|
364
396
|
|
|
365
397
|
## Walkthroughs
|
|
366
398
|
|
|
@@ -467,6 +499,20 @@ by keeping the prover around. Removing it on prune and rebuilding on re-add is
|
|
|
467
499
|
correct and simpler; the expensive block-rollup proofs are still reused when content re-appears,
|
|
468
500
|
because the proving broker is content-addressed independently of the prover's lifetime.
|
|
469
501
|
|
|
502
|
+
### How is a genuine failure told apart from a prune, without a racy classification?
|
|
503
|
+
|
|
504
|
+
Knowledge of an L1 reorg reaches the prover-node on two causally unordered channels: the control
|
|
505
|
+
plane (`chain-pruned` → `onPrune`) and the data plane (world-state unwinds, and an in-flight fork
|
|
506
|
+
read faults inside a `CheckpointProver` mid-proof). If the `EpochSession` reacted to a fault by asking
|
|
507
|
+
"was this a prune or a genuine failure?", every answer would sample control-plane state that lags the
|
|
508
|
+
data-plane unwind — racy by construction. We remove the question by pushing the fact down to where it
|
|
509
|
+
is unambiguous: a `CheckpointProver` records `isFailed()` when *its* block proofs reject. The session
|
|
510
|
+
then reads a clean signal: if any prover failed, the fault might be a prune (`stopped`) — don't upload,
|
|
511
|
+
don't rebuild over it, recover on re-add; if *no* prover failed yet the session's own top-tree/submit
|
|
512
|
+
work failed, that is definitively **not** a prune (`failed`) — a genuine, race-free failure that is
|
|
513
|
+
retained (so a deterministic failure isn't re-proved every tick) and uploaded once. No control-plane
|
|
514
|
+
sampling, no timing race — the two prover-level and session-level facts carry the whole decision.
|
|
515
|
+
|
|
470
516
|
## Configuration
|
|
471
517
|
|
|
472
518
|
| Env var | Description |
|
|
@@ -475,7 +521,7 @@ because the proving broker is content-addressed independently of the prover's li
|
|
|
475
521
|
| `PROVER_NODE_MAX_PENDING_JOBS` | Cap on the number of non-terminal `EpochSession`s (full + partial). When at limit, reconcile defers opening new full `EpochSession`s; explicit `startProof` calls throw. |
|
|
476
522
|
| `PROVER_NODE_EPOCH_PROVING_DELAY_MS` | Optional sleep at the start of each `EpochSession`, before the TopTreeJob is constructed. Used in tests to give late events time to land. |
|
|
477
523
|
| `TX_GATHERING_TIMEOUT_MS` | Per-block tx gather deadline used by each `CheckpointProver`. |
|
|
478
|
-
| `PROVER_NODE_FAILED_EPOCH_STORE` | If set,
|
|
524
|
+
| `PROVER_NODE_FAILED_EPOCH_STORE` | If set, a full session that fails on its own account (top-tree/submit, provers healthy) uploads its proving data (every `CheckpointProver`'s txs + register-time data, regardless of sub-tree completion) to this file store. |
|
|
479
525
|
| `PROVER_NODE_DISABLE_PROOF_PUBLISH` | If true, the publishing service runs `analyzeEpochProofSubmission` (estimates L1 fees) instead of actually submitting. |
|
|
480
526
|
|
|
481
527
|
## Failure handling and observability
|
|
@@ -493,14 +539,29 @@ Loggers:
|
|
|
493
539
|
- `prover-node:checkpoint-prover` — sub-tree pipeline (gather, block processing).
|
|
494
540
|
- `prover-client:chonk-cache` — chonk-verifier cache enqueue / release events.
|
|
495
541
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
`
|
|
502
|
-
|
|
503
|
-
|
|
542
|
+
Failed proving data is uploaded to the configured file store (`PROVER_NODE_FAILED_EPOCH_STORE`) at two
|
|
543
|
+
levels, and re-proved offline by the matching downloader/rerunner: an epoch job via
|
|
544
|
+
`downloadEpochProvingJob` + `rerunEpochProvingJob`, and a single checkpoint via the same download plus
|
|
545
|
+
`rerunCheckpointProvingJob` (which rebuilds just that checkpoint's sub-tree prover and awaits its block
|
|
546
|
+
proofs — no epoch top-tree or L1 submit). Both upload levels build an `EpochProvingJobData` snapshot with
|
|
547
|
+
`SessionManager.buildProvingData(...)` — every `CheckpointProver`'s txs and register-time data, even if
|
|
548
|
+
its sub-tree never reached `isCompleted()` — and ship it via `uploadEpochProofFailure` alongside a
|
|
549
|
+
world-state + archiver backup:
|
|
550
|
+
|
|
551
|
+
- **Per checkpoint.** When a `CheckpointProver`'s block proofs reject for a non-cancel reason (a sub-tree
|
|
552
|
+
fault or a prune-induced fork fault), it fires its `onFailed` callback and `ProverNode` uploads that one
|
|
553
|
+
checkpoint via `tryUploadCheckpointFailure(prover)`. This fires for prune-induced faults too — that is
|
|
554
|
+
intentional; a prune-caused checkpoint snapshot is harmless, and *not* trying to tell prune from genuine
|
|
555
|
+
failure is exactly what keeps this race-free. A cancelled prover (control-plane prune / shutdown) is not
|
|
556
|
+
a failure and does not upload.
|
|
557
|
+
- **Per session.** When a full session ends in its own genuine failure (`EpochSession.hasFailed()` —
|
|
558
|
+
top-tree/submit failed with every prover healthy), the session manager fires `onSessionFailed` and
|
|
559
|
+
`ProverNode` uploads all the session's checkpoints via `tryUploadEpochFailure(...)`. This is race-free
|
|
560
|
+
(healthy provers rule out a prune) and fires once, since the failed session is retained and never re-run.
|
|
561
|
+
|
|
562
|
+
A `stopped` session (a prover under it failed) does not upload at the session level — its failed checkpoint
|
|
563
|
+
already uploaded itself. Each backup is a full world-state + archiver snapshot, so a prune that faults
|
|
564
|
+
several in-flight provers produces several uploads; this is accepted for the diagnostic value.
|
|
504
565
|
|
|
505
566
|
Metrics emitted by `EpochSession`s:
|
|
506
567
|
|
|
@@ -4,10 +4,19 @@ import { type ProverClientConfig } from '@aztec/prover-client';
|
|
|
4
4
|
import { ProverBrokerConfig } from '@aztec/prover-client/broker';
|
|
5
5
|
import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
|
|
6
6
|
import type { GenesisData } from '@aztec/stdlib/world-state';
|
|
7
|
+
type RerunConfig = DataStoreConfig & ProverBrokerConfig & ProverClientConfig & Pick<L1ContractsConfig, 'aztecEpochDuration'>;
|
|
7
8
|
/**
|
|
8
9
|
* Given a local folder where `downloadEpochProvingJob` was called, creates a new archiver and world state
|
|
9
10
|
* using the state snapshots, and creates a new epoch proving session to prove the downloaded proving job.
|
|
10
11
|
* Proving is done with a local proving broker and agents as specified by the config.
|
|
11
12
|
*/
|
|
12
|
-
export declare function rerunEpochProvingJob(localPath: string, log: Logger, config:
|
|
13
|
-
|
|
13
|
+
export declare function rerunEpochProvingJob(localPath: string, log: Logger, config: RerunConfig, genesis?: GenesisData): Promise<"awaiting-checkpoints" | "awaiting-predecessor" | "awaiting-root" | "cancelled" | "completed" | "failed" | "initialized" | "publishing-proof" | "stopped" | "superseded" | "timed-out">;
|
|
14
|
+
/**
|
|
15
|
+
* Re-proves a single downloaded checkpoint proving job (as uploaded by a `CheckpointProver` failure).
|
|
16
|
+
* Reconstructs just that checkpoint's sub-tree prover from the snapshot and awaits its block proofs — no
|
|
17
|
+
* epoch top-tree, no L1 submission — so a checkpoint-level failure can be reproduced offline in isolation.
|
|
18
|
+
* Returns the block-rollup proof outputs on success; throws if the checkpoint fails to prove again.
|
|
19
|
+
*/
|
|
20
|
+
export declare function rerunCheckpointProvingJob(localPath: string, log: Logger, config: RerunConfig, genesis?: GenesisData): Promise<import("@aztec/stdlib/interfaces/server").PublicInputsAndRecursiveProof<import("@aztec/stdlib/rollup").BlockRollupPublicInputs, 480>[]>;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVydW4tZXBvY2gtcHJvdmluZy1qb2IuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hY3Rpb25zL3JlcnVuLWVwb2NoLXByb3Zpbmctam9iLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFaEUsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFcEQsT0FBTyxFQUFFLEtBQUssa0JBQWtCLEVBQXNCLE1BQU0sc0JBQXNCLENBQUM7QUFDbkYsT0FBTyxFQUFFLGtCQUFrQixFQUErQixNQUFNLDZCQUE2QixDQUFDO0FBTzlGLE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRzlELE9BQU8sS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBVzdELEtBQUssV0FBVyxHQUFHLGVBQWUsR0FDaEMsa0JBQWtCLEdBQ2xCLGtCQUFrQixHQUNsQixJQUFJLENBQUMsaUJBQWlCLEVBQUUsb0JBQW9CLENBQUMsQ0FBQztBQUVoRDs7OztHQUlHO0FBQ0gsd0JBQXNCLG9CQUFvQixDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLE9BQU8sQ0FBQyxFQUFFLFdBQVcsbU1Bc0NwSDtBQUVEOzs7OztHQUtHO0FBQ0gsd0JBQXNCLHlCQUF5QixDQUM3QyxTQUFTLEVBQUUsTUFBTSxFQUNqQixHQUFHLEVBQUUsTUFBTSxFQUNYLE1BQU0sRUFBRSxXQUFXLEVBQ25CLE9BQU8sQ0FBQyxFQUFFLFdBQVcsbUpBaUJ0QiJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rerun-epoch-proving-job.d.ts","sourceRoot":"","sources":["../../src/actions/rerun-epoch-proving-job.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,EAAE,KAAK,kBAAkB,EAAsB,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAA+B,MAAM,6BAA6B,CAAC;AAO9F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAW7D;;;;GAIG;AACH,wBAAsB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"rerun-epoch-proving-job.d.ts","sourceRoot":"","sources":["../../src/actions/rerun-epoch-proving-job.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,EAAE,KAAK,kBAAkB,EAAsB,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAA+B,MAAM,6BAA6B,CAAC;AAO9F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAW7D,KAAK,WAAW,GAAG,eAAe,GAChC,kBAAkB,GAClB,kBAAkB,GAClB,IAAI,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,CAAC;AAEhD;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,WAAW,mMAsCpH;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,WAAW,EACnB,OAAO,CAAC,EAAE,WAAW,mJAiBtB"}
|
|
@@ -20,53 +20,19 @@ import { ProverNodeJobMetrics } from '../metrics.js';
|
|
|
20
20
|
* using the state snapshots, and creates a new epoch proving session to prove the downloaded proving job.
|
|
21
21
|
* Proving is done with a local proving broker and agents as specified by the config.
|
|
22
22
|
*/ export async function rerunEpochProvingJob(localPath, log, config, genesis) {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const publicProcessorFactory = new PublicProcessorFactory(createContractDataSource(archiver), undefined, undefined, log.getBindings());
|
|
23
|
+
const ctx = await createRerunContext(localPath, log, config, genesis);
|
|
24
|
+
const { jobData, prover, metrics } = ctx;
|
|
25
|
+
log.info(`Rerunning epoch proving for epoch ${jobData.epochNumber}`);
|
|
26
|
+
const provers = [];
|
|
27
|
+
for(let i = 0; i < jobData.checkpoints.length; i++){
|
|
28
|
+
provers.push(await buildCheckpointProver(ctx, i, log));
|
|
29
|
+
}
|
|
31
30
|
// Local rerun never publishes — stub the service so submit() always resolves 'published'
|
|
32
31
|
// and withdraw is a no-op.
|
|
33
32
|
const publishingService = {
|
|
34
33
|
submit: ()=>Promise.resolve('published'),
|
|
35
34
|
withdraw: ()=>{}
|
|
36
35
|
};
|
|
37
|
-
const broker = await createAndStartProvingBroker(config, telemetry);
|
|
38
|
-
const prover = await createProverClient(config, worldState, broker, telemetry);
|
|
39
|
-
const chonkCache = new ChonkCache(log.getBindings());
|
|
40
|
-
const txProvider = makeReplayingTxProvider(jobData.txs);
|
|
41
|
-
log.info(`Rerunning epoch proving for epoch ${jobData.epochNumber}`);
|
|
42
|
-
const provers = [];
|
|
43
|
-
for(let i = 0; i < jobData.checkpoints.length; i++){
|
|
44
|
-
const checkpoint = jobData.checkpoints[i];
|
|
45
|
-
const previousBlockHeader = i === 0 ? jobData.previousBlockHeader : jobData.checkpoints[i - 1].blocks.at(-1).header;
|
|
46
|
-
const l1ToL2Messages = jobData.l1ToL2Messages[checkpoint.number] ?? [];
|
|
47
|
-
const previousArchiveSiblingPath = await getLastSiblingPath(MerkleTreeId.ARCHIVE, worldState.getSnapshot(BlockNumber(checkpoint.blocks[0].number - 1)));
|
|
48
|
-
const attestations = checkpoint.number === jobData.checkpoints.at(-1).number ? jobData.attestations : [];
|
|
49
|
-
provers.push(new CheckpointProver({
|
|
50
|
-
checkpoint,
|
|
51
|
-
epochNumber: jobData.epochNumber,
|
|
52
|
-
attestations,
|
|
53
|
-
previousBlockHeader,
|
|
54
|
-
l1ToL2Messages,
|
|
55
|
-
previousArchiveSiblingPath
|
|
56
|
-
}, {
|
|
57
|
-
proverFactory: prover,
|
|
58
|
-
chonkCache,
|
|
59
|
-
publicProcessorFactory,
|
|
60
|
-
dbProvider: worldState,
|
|
61
|
-
txProvider,
|
|
62
|
-
dateProvider: new DateProvider(),
|
|
63
|
-
proverId: prover.getProverId(),
|
|
64
|
-
metrics,
|
|
65
|
-
txGatheringTimeoutMs: 120_000,
|
|
66
|
-
deadline: undefined,
|
|
67
|
-
log
|
|
68
|
-
}));
|
|
69
|
-
}
|
|
70
36
|
const l1Constants = {
|
|
71
37
|
epochDuration: config.aztecEpochDuration
|
|
72
38
|
};
|
|
@@ -93,6 +59,82 @@ import { ProverNodeJobMetrics } from '../metrics.js';
|
|
|
93
59
|
});
|
|
94
60
|
return finalState;
|
|
95
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Re-proves a single downloaded checkpoint proving job (as uploaded by a `CheckpointProver` failure).
|
|
64
|
+
* Reconstructs just that checkpoint's sub-tree prover from the snapshot and awaits its block proofs — no
|
|
65
|
+
* epoch top-tree, no L1 submission — so a checkpoint-level failure can be reproduced offline in isolation.
|
|
66
|
+
* Returns the block-rollup proof outputs on success; throws if the checkpoint fails to prove again.
|
|
67
|
+
*/ export async function rerunCheckpointProvingJob(localPath, log, config, genesis) {
|
|
68
|
+
const ctx = await createRerunContext(localPath, log, config, genesis);
|
|
69
|
+
const { jobData } = ctx;
|
|
70
|
+
const checkpointNumber = jobData.checkpoints[0].number;
|
|
71
|
+
log.info(`Rerunning checkpoint proving for checkpoint ${checkpointNumber} (epoch ${jobData.epochNumber})`);
|
|
72
|
+
const prover = await buildCheckpointProver(ctx, 0, log);
|
|
73
|
+
try {
|
|
74
|
+
const blockProofs = await prover.whenBlockProofsReady();
|
|
75
|
+
log.info(`Completed proving for checkpoint ${checkpointNumber} with ${blockProofs.length} block proof(s)`);
|
|
76
|
+
return blockProofs;
|
|
77
|
+
} finally{
|
|
78
|
+
prover.cancel({
|
|
79
|
+
routine: true
|
|
80
|
+
});
|
|
81
|
+
await prover.whenDone();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Rebuilds the offline proving environment from a downloaded job: world state + archiver from the
|
|
86
|
+
* snapshots, a local proving broker + client, a chonk cache, and a tx provider that replays the job's txs.
|
|
87
|
+
*/ async function createRerunContext(localPath, log, config, genesis) {
|
|
88
|
+
const jobData = deserializeEpochProvingJobData(readFileSync(localPath));
|
|
89
|
+
log.info(`Loaded proving job data for epoch ${jobData.epochNumber}`);
|
|
90
|
+
const telemetry = getTelemetryClient();
|
|
91
|
+
const metrics = new ProverNodeJobMetrics(telemetry.getMeter('prover-job'), telemetry.getTracer('prover-job'));
|
|
92
|
+
const worldState = await createWorldState(config, genesis);
|
|
93
|
+
const initialBlockHash = await worldState.getInitialHeader().hash();
|
|
94
|
+
const archiver = await createArchiverStore(config, initialBlockHash);
|
|
95
|
+
const publicProcessorFactory = new PublicProcessorFactory(createContractDataSource(archiver), undefined, undefined, log.getBindings());
|
|
96
|
+
const broker = await createAndStartProvingBroker(config, telemetry);
|
|
97
|
+
const prover = await createProverClient(config, worldState, broker, telemetry);
|
|
98
|
+
const chonkCache = new ChonkCache(log.getBindings());
|
|
99
|
+
const txProvider = makeReplayingTxProvider(jobData.txs);
|
|
100
|
+
return {
|
|
101
|
+
jobData,
|
|
102
|
+
metrics,
|
|
103
|
+
worldState,
|
|
104
|
+
publicProcessorFactory,
|
|
105
|
+
prover,
|
|
106
|
+
chonkCache,
|
|
107
|
+
txProvider
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/** Reconstructs the `CheckpointProver` for the checkpoint at `index` in the job, ready to prove. */ async function buildCheckpointProver(ctx, index, log) {
|
|
111
|
+
const { jobData, worldState, prover, chonkCache, publicProcessorFactory, txProvider, metrics } = ctx;
|
|
112
|
+
const checkpoint = jobData.checkpoints[index];
|
|
113
|
+
const previousBlockHeader = index === 0 ? jobData.previousBlockHeader : jobData.checkpoints[index - 1].blocks.at(-1).header;
|
|
114
|
+
const l1ToL2Messages = jobData.l1ToL2Messages[checkpoint.number] ?? [];
|
|
115
|
+
const previousArchiveSiblingPath = await getLastSiblingPath(MerkleTreeId.ARCHIVE, worldState.getSnapshot(BlockNumber(checkpoint.blocks[0].number - 1)));
|
|
116
|
+
const attestations = checkpoint.number === jobData.checkpoints.at(-1).number ? jobData.attestations : [];
|
|
117
|
+
return new CheckpointProver({
|
|
118
|
+
checkpoint,
|
|
119
|
+
epochNumber: jobData.epochNumber,
|
|
120
|
+
attestations,
|
|
121
|
+
previousBlockHeader,
|
|
122
|
+
l1ToL2Messages,
|
|
123
|
+
previousArchiveSiblingPath
|
|
124
|
+
}, {
|
|
125
|
+
proverFactory: prover,
|
|
126
|
+
chonkCache,
|
|
127
|
+
publicProcessorFactory,
|
|
128
|
+
dbProvider: worldState,
|
|
129
|
+
txProvider,
|
|
130
|
+
dateProvider: new DateProvider(),
|
|
131
|
+
proverId: prover.getProverId(),
|
|
132
|
+
metrics,
|
|
133
|
+
txGatheringTimeoutMs: 120_000,
|
|
134
|
+
deadline: undefined,
|
|
135
|
+
log
|
|
136
|
+
});
|
|
137
|
+
}
|
|
96
138
|
/** Build a synthetic ITxProvider that returns the supplied txs map by lookup. */ function makeReplayingTxProvider(txs) {
|
|
97
139
|
const lookup = (hashes)=>{
|
|
98
140
|
const found = [];
|
|
@@ -3,7 +3,7 @@ import { type LoggerBindings } from '@aztec/foundation/log';
|
|
|
3
3
|
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
4
4
|
import type { Checkpoint } from '@aztec/stdlib/checkpoint';
|
|
5
5
|
import { type L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
6
|
-
import { CheckpointProver, type CheckpointProverArgs, type CheckpointProverDeps } from './job/checkpoint-prover.js';
|
|
6
|
+
import { CheckpointProver, type CheckpointProverArgs, type CheckpointProverDeps, type CheckpointProverTestHooks } from './job/checkpoint-prover.js';
|
|
7
7
|
/** Register-time data needed to construct a `CheckpointProver` (everything except the checkpoint + epoch). */
|
|
8
8
|
export type RegisterCheckpointData = Omit<CheckpointProverArgs, 'checkpoint' | 'epochNumber'>;
|
|
9
9
|
/** Factory used by the store to construct new provers. Tests can inject a stub. */
|
|
@@ -34,6 +34,8 @@ export declare class CheckpointStore {
|
|
|
34
34
|
*/
|
|
35
35
|
private readonly pendingTeardowns;
|
|
36
36
|
private nextTeardownId;
|
|
37
|
+
/** Test-only hooks injected into every prover this store constructs. */
|
|
38
|
+
private testHooks;
|
|
37
39
|
private readonly log;
|
|
38
40
|
constructor(l2BlockSource: Pick<L2BlockSource, 'getL1Constants'>, proverDeps: Omit<CheckpointProverDeps, 'log'>, bindings?: LoggerBindings, proverFactoryFn?: CheckpointProverFactory);
|
|
39
41
|
start(): Promise<void>;
|
|
@@ -49,6 +51,11 @@ export declare class CheckpointStore {
|
|
|
49
51
|
* still-canonical content); otherwise a new prover is constructed.
|
|
50
52
|
*/
|
|
51
53
|
addOrUpdate(checkpoint: Checkpoint, data: RegisterCheckpointData): Promise<CheckpointProver>;
|
|
54
|
+
/**
|
|
55
|
+
* Installs test-only hooks applied to every prover constructed from now on. Used by the e2e harness to
|
|
56
|
+
* force a checkpoint sub-tree failure without monkey-patching the prover factory.
|
|
57
|
+
*/
|
|
58
|
+
setTestHooks(hooks: CheckpointProverTestHooks): void;
|
|
52
59
|
/**
|
|
53
60
|
* Cancels and removes every prover that holds a block above the prune target. A checkpoint is orphaned by a prune to
|
|
54
61
|
* block `targetBlockNumber` iff its last block sits above the target — including a checkpoint whose range straddles
|
|
@@ -85,4 +92,4 @@ export declare class CheckpointStore {
|
|
|
85
92
|
}
|
|
86
93
|
/** Sub-set of `L1RollupConstants` actually consumed by the store's slot helpers. */
|
|
87
94
|
export type CheckpointStoreL1Constants = Pick<L1RollupConstants, 'epochDuration'>;
|
|
88
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
95
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludC1zdG9yZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NoZWNrcG9pbnQtc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsV0FBVyxFQUFvQixXQUFXLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDOUcsT0FBTyxFQUFlLEtBQUssY0FBYyxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBQ3ZGLE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxLQUFLLGlCQUFpQixFQUF3QyxNQUFNLDZCQUE2QixDQUFDO0FBRTNHLE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsS0FBSyxvQkFBb0IsRUFDekIsS0FBSyxvQkFBb0IsRUFDekIsS0FBSyx5QkFBeUIsRUFDL0IsTUFBTSw0QkFBNEIsQ0FBQztBQUVwQyw4R0FBOEc7QUFDOUcsTUFBTSxNQUFNLHNCQUFzQixHQUFHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxZQUFZLEdBQUcsYUFBYSxDQUFDLENBQUM7QUFFOUYsbUZBQW1GO0FBQ25GLE1BQU0sTUFBTSx1QkFBdUIsR0FBRyxDQUFDLElBQUksRUFBRSxvQkFBb0IsRUFBRSxJQUFJLEVBQUUsb0JBQW9CLEtBQUssZ0JBQWdCLENBQUM7QUFFbkg7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILHFCQUFhLGVBQWU7SUFjeEIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhO0lBQzlCLE9BQU8sQ0FBQyxRQUFRLENBQUMsVUFBVTtJQUUzQixPQUFPLENBQUMsUUFBUSxDQUFDLGVBQWU7SUFoQmxDLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUF1QztJQUMvRDs7OztPQUlHO0lBQ0gsT0FBTyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBb0M7SUFDckUsT0FBTyxDQUFDLGNBQWMsQ0FBSztJQUMzQix3RUFBd0U7SUFDeEUsT0FBTyxDQUFDLFNBQVMsQ0FBaUM7SUFDbEQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQVM7SUFFN0IsWUFDbUIsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsZ0JBQWdCLENBQUMsRUFDcEQsVUFBVSxFQUFFLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxLQUFLLENBQUMsRUFDOUQsUUFBUSxDQUFDLEVBQUUsY0FBYyxFQUNSLGVBQWUsR0FBRSx1QkFBMEUsRUFHN0c7SUFFTSxLQUFLLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUU1QjtJQUVZLElBQUksSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBU2pDO0lBRUQ7OztPQUdHO0lBQ0gsT0FBTyxDQUFDLGFBQWE7SUFPckI7Ozs7T0FJRztJQUNVLFdBQVcsQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxzQkFBc0IsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0E2QnhHO0lBRUQ7OztPQUdHO0lBQ0ksWUFBWSxDQUFDLEtBQUssRUFBRSx5QkFBeUIsR0FBRyxJQUFJLENBRTFEO0lBRUQ7Ozs7Ozs7Ozs7O09BV0c7SUFDSSx5QkFBeUIsQ0FBQyxpQkFBaUIsRUFBRSxXQUFXLEdBQUcsZ0JBQWdCLEVBQUUsQ0FZbkY7SUFFRDs7OztPQUlHO0lBQ0ksV0FBVyxDQUFDLFlBQVksRUFBRSxXQUFXLEdBQUcsSUFBSSxDQWlCbEQ7SUFFRCw2REFBNkQ7SUFDdEQsR0FBRyxDQUFDLEVBQUUsRUFBRSxNQUFNLEdBQUcsZ0JBQWdCLEdBQUcsU0FBUyxDQUVuRDtJQUVELGtHQUFrRztJQUMzRixlQUFlLENBQUMsVUFBVSxFQUFFLFVBQVUsR0FBRyxnQkFBZ0IsR0FBRyxTQUFTLENBRTNFO0lBRUQsK0RBQStEO0lBQ3hELE9BQU8sSUFBSSxnQkFBZ0IsRUFBRSxDQUVuQztJQUVELHlEQUF5RDtJQUNsRCxJQUFJLElBQUksZ0JBQWdCLEVBQUUsQ0FFaEM7SUFFRDs7T0FFRztJQUNVLFlBQVksQ0FBQyxLQUFLLEVBQUUsV0FBVyxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBSXpFO0lBRUQseUZBQXlGO0lBQ2xGLGVBQWUsQ0FBQyxRQUFRLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxVQUFVLEdBQUcsZ0JBQWdCLEVBQUUsQ0FFbkY7Q0FDRjtBQUVELG9GQUFvRjtBQUNwRixNQUFNLE1BQU0sMEJBQTBCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLGVBQWUsQ0FBQyxDQUFDIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkpoint-store.d.ts","sourceRoot":"","sources":["../src/checkpoint-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAoB,WAAW,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC9G,OAAO,EAAe,KAAK,cAAc,EAAgB,MAAM,uBAAuB,CAAC;AACvF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,KAAK,iBAAiB,EAAwC,MAAM,6BAA6B,CAAC;AAE3G,OAAO,
|
|
1
|
+
{"version":3,"file":"checkpoint-store.d.ts","sourceRoot":"","sources":["../src/checkpoint-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAoB,WAAW,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC9G,OAAO,EAAe,KAAK,cAAc,EAAgB,MAAM,uBAAuB,CAAC;AACvF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,KAAK,iBAAiB,EAAwC,MAAM,6BAA6B,CAAC;AAE3G,OAAO,EACL,gBAAgB,EAChB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC/B,MAAM,4BAA4B,CAAC;AAEpC,8GAA8G;AAC9G,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,oBAAoB,EAAE,YAAY,GAAG,aAAa,CAAC,CAAC;AAE9F,mFAAmF;AACnF,MAAM,MAAM,uBAAuB,GAAG,CAAC,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,oBAAoB,KAAK,gBAAgB,CAAC;AAEnH;;;;;;;;;;;;;GAaG;AACH,qBAAa,eAAe;IAcxB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAE3B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAhBlC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAoC;IACrE,OAAO,CAAC,cAAc,CAAK;IAC3B,wEAAwE;IACxE,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B,YACmB,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,gBAAgB,CAAC,EACpD,UAAU,EAAE,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,EAC9D,QAAQ,CAAC,EAAE,cAAc,EACR,eAAe,GAAE,uBAA0E,EAG7G;IAEM,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE5B;IAEY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CASjC;IAED;;;OAGG;IACH,OAAO,CAAC,aAAa;IAOrB;;;;OAIG;IACU,WAAW,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA6BxG;IAED;;;OAGG;IACI,YAAY,CAAC,KAAK,EAAE,yBAAyB,GAAG,IAAI,CAE1D;IAED;;;;;;;;;;;OAWG;IACI,yBAAyB,CAAC,iBAAiB,EAAE,WAAW,GAAG,gBAAgB,EAAE,CAYnF;IAED;;;;OAIG;IACI,WAAW,CAAC,YAAY,EAAE,WAAW,GAAG,IAAI,CAiBlD;IAED,6DAA6D;IACtD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAEnD;IAED,kGAAkG;IAC3F,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG,gBAAgB,GAAG,SAAS,CAE3E;IAED,+DAA+D;IACxD,OAAO,IAAI,gBAAgB,EAAE,CAEnC;IAED,yDAAyD;IAClD,IAAI,IAAI,gBAAgB,EAAE,CAEhC;IAED;;OAEG;IACU,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAIzE;IAED,yFAAyF;IAClF,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAG,gBAAgB,EAAE,CAEnF;CACF;AAED,oFAAoF;AACpF,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC"}
|
package/dest/checkpoint-store.js
CHANGED
|
@@ -25,6 +25,7 @@ import { CheckpointProver } from './job/checkpoint-prover.js';
|
|
|
25
25
|
* teardowns for the same content id in flight at once, which a content-id key would clobber.
|
|
26
26
|
*/ pendingTeardowns;
|
|
27
27
|
nextTeardownId;
|
|
28
|
+
/** Test-only hooks injected into every prover this store constructs. */ testHooks;
|
|
28
29
|
log;
|
|
29
30
|
constructor(l2BlockSource, proverDeps, bindings, proverFactoryFn = (args, deps)=>new CheckpointProver(args, deps)){
|
|
30
31
|
this.l2BlockSource = l2BlockSource;
|
|
@@ -33,6 +34,7 @@ import { CheckpointProver } from './job/checkpoint-prover.js';
|
|
|
33
34
|
this.provers = new Map();
|
|
34
35
|
this.pendingTeardowns = new Map();
|
|
35
36
|
this.nextTeardownId = 0;
|
|
37
|
+
this.testHooks = {};
|
|
36
38
|
this.log = createLogger('prover-node:checkpoint-store', bindings);
|
|
37
39
|
}
|
|
38
40
|
start() {
|
|
@@ -87,12 +89,19 @@ import { CheckpointProver } from './job/checkpoint-prover.js';
|
|
|
87
89
|
epochNumber
|
|
88
90
|
}, {
|
|
89
91
|
...this.proverDeps,
|
|
92
|
+
checkpointProveOverride: this.testHooks.checkpointProveOverride,
|
|
90
93
|
log: this.log
|
|
91
94
|
});
|
|
92
95
|
this.provers.set(id, prover);
|
|
93
96
|
return prover;
|
|
94
97
|
}
|
|
95
98
|
/**
|
|
99
|
+
* Installs test-only hooks applied to every prover constructed from now on. Used by the e2e harness to
|
|
100
|
+
* force a checkpoint sub-tree failure without monkey-patching the prover factory.
|
|
101
|
+
*/ setTestHooks(hooks) {
|
|
102
|
+
this.testHooks = hooks;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
96
105
|
* Cancels and removes every prover that holds a block above the prune target. A checkpoint is orphaned by a prune to
|
|
97
106
|
* block `targetBlockNumber` iff its last block sits above the target — including a checkpoint whose range straddles
|
|
98
107
|
* the target (partially orphaned), which block-range marking catches without boundary ambiguity. Keying off the
|
|
@@ -29,8 +29,23 @@ export type CheckpointProverDeps = {
|
|
|
29
29
|
txGatheringTimeoutMs: number;
|
|
30
30
|
/** Public processor deadline. */
|
|
31
31
|
deadline: Date | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Fired once when the prover's block proofs reject for a genuine (non-cancel) reason — a sub-tree
|
|
34
|
+
* fault or a prune-induced fork fault. Useful for performing post mortem on failures.
|
|
35
|
+
*/
|
|
36
|
+
onFailed?: (prover: CheckpointProver) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Test-only hook: if set, invoked at the start of checkpoint execution instead of proving. Lets e2e
|
|
39
|
+
* tests force a sub-tree failure (it should throw) to exercise the checkpoint failure/upload path.
|
|
40
|
+
*/
|
|
41
|
+
checkpointProveOverride?: () => Promise<never>;
|
|
32
42
|
log: Logger;
|
|
33
43
|
};
|
|
44
|
+
/** Test-only hooks the store injects into every `CheckpointProver` it constructs. */
|
|
45
|
+
export type CheckpointProverTestHooks = {
|
|
46
|
+
/** If set, invoked at the start of checkpoint execution instead of proving; should throw to fail. */
|
|
47
|
+
checkpointProveOverride?: () => Promise<never>;
|
|
48
|
+
};
|
|
34
49
|
/** Inputs that fully describe a checkpoint at register time. */
|
|
35
50
|
export type CheckpointProverArgs = {
|
|
36
51
|
checkpoint: Checkpoint;
|
|
@@ -76,9 +91,13 @@ export declare class CheckpointProver {
|
|
|
76
91
|
readonly txs: Map<string, Tx>;
|
|
77
92
|
/** Resolved by the sub-tree on success, rejected on cancel/failure. */
|
|
78
93
|
private readonly blockProofs;
|
|
94
|
+
/** Block-level proving was fully *enqueued* (a progress marker; the sub-tree may still be proving). */
|
|
95
|
+
private completed;
|
|
96
|
+
/** Block proofs rejected for a genuine (non-cancel) reason — a sub-tree or prune-induced fork fault. */
|
|
97
|
+
private failed;
|
|
98
|
+
/** The prover was torn down (prune / reap / shutdown). */
|
|
79
99
|
private cancelled;
|
|
80
100
|
private subTree?;
|
|
81
|
-
private completed;
|
|
82
101
|
private readonly abortController;
|
|
83
102
|
/** Tracks the eager gather+execute task so `cancel()` and `whenDone()` can await its unwind. */
|
|
84
103
|
private readonly runPromise;
|
|
@@ -92,8 +111,13 @@ export declare class CheckpointProver {
|
|
|
92
111
|
*/
|
|
93
112
|
static idFor(checkpoint: Checkpoint): string;
|
|
94
113
|
isCancelled(): boolean;
|
|
95
|
-
/**
|
|
96
|
-
|
|
114
|
+
/**
|
|
115
|
+
* True once this prover's block proofs have rejected for a genuine (non-cancel) reason — a sub-tree
|
|
116
|
+
* proving fault or a prune-induced world-state fork fault. A failed prover cannot produce its block
|
|
117
|
+
* proofs, so the reconciler must not build (or rebuild) an EpochSession over it; it is cleared only by
|
|
118
|
+
* a prune/re-add replacing it with a fresh prover, or by expiry reaping it.
|
|
119
|
+
*/
|
|
120
|
+
isFailed(): boolean;
|
|
97
121
|
/** AbortSignal that fires on cancel — for callers that want to wire their own tasks. */
|
|
98
122
|
getAbortSignal(): AbortSignal;
|
|
99
123
|
/** Promise that resolves with the block-rollup proofs for this checkpoint (or rejects on cancel/failure). */
|
|
@@ -101,6 +125,12 @@ export declare class CheckpointProver {
|
|
|
101
125
|
/** Resolves when all in-flight work for this prover has fully unwound. */
|
|
102
126
|
whenDone(): Promise<void>;
|
|
103
127
|
private gatherAndExecute;
|
|
128
|
+
/**
|
|
129
|
+
* Rejects the block-proof promise and, unless this is a cancellation, records the prover as failed so
|
|
130
|
+
* the reconciler won't build an EpochSession over it. First rejection wins, so a later duplicate reject
|
|
131
|
+
* (e.g. the executeCheckpoint `finally`) is a harmless no-op.
|
|
132
|
+
*/
|
|
133
|
+
private failBlockProofs;
|
|
104
134
|
private gatherTxs;
|
|
105
135
|
private executeCheckpoint;
|
|
106
136
|
/**
|
|
@@ -121,4 +151,4 @@ export declare class CheckpointProver {
|
|
|
121
151
|
private processTxs;
|
|
122
152
|
private createFork;
|
|
123
153
|
}
|
|
124
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
154
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludC1wcm92ZXIuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9qb2IvY2hlY2twb2ludC1wcm92ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssY0FBYyxFQUF1QyxNQUFNLGtCQUFrQixDQUFDO0FBQzVGLE9BQU8sRUFBZSxLQUFLLFdBQVcsRUFBRSxLQUFLLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRWpHLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNoRSxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUVwRCxPQUFPLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsS0FBSyxZQUFZLEVBQVMsTUFBTSx5QkFBeUIsQ0FBQztBQUduRSxPQUFPLEtBQUssRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQy9ELE9BQU8sS0FBSyxFQUFpQyxVQUFVLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDbEgsT0FBTyxLQUFLLEVBQW1CLHNCQUFzQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFdkYsT0FBTyxLQUFLLEVBQUUsb0JBQW9CLEVBQVcsTUFBTSxxQkFBcUIsQ0FBQztBQUN6RSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEtBQUssRUFBRSx3QkFBd0IsRUFBRSxXQUFXLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUc3RixPQUFPLEtBQUssRUFBRSxXQUFXLEVBQWUsRUFBRSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFckUsT0FBTyxLQUFLLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxlQUFlLENB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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkpoint-prover.d.ts","sourceRoot":"","sources":["../../src/job/checkpoint-prover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAuC,MAAM,kBAAkB,CAAC;AAC5F,OAAO,EAAe,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAEjG,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,yBAAyB,CAAC;AAGnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAiC,UAAU,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAClH,OAAO,KAAK,EAAmB,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEvF,OAAO,KAAK,EAAE,oBAAoB,EAAW,MAAM,qBAAqB,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,wBAAwB,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAG7F,OAAO,KAAK,EAAE,WAAW,EAAe,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAErE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,+DAA+D;AAC/D,MAAM,MAAM,oBAAoB,GAAG;IACjC,aAAa,EAAE,kBAAkB,CAAC;IAClC,0EAA0E;IAC1E,UAAU,EAAE,UAAU,CAAC;IACvB,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,UAAU,EAAE,IAAI,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;IACnD,UAAU,EAAE,WAAW,CAAC;IACxB,6FAA2F;IAC3F,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,UAAU,CAAC;IACrB,OAAO,EAAE,oBAAoB,CAAC;IAC9B,6BAA6B;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iCAAiC;IACjC,QAAQ,EAAE,IAAI,GAAG,SAAS,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,gEAAgE;AAChE,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,EAAE,UAAU,CAAC;IACvB,qGAAqG;IACrG,WAAW,EAAE,WAAW,CAAC;IACzB,YAAY,EAAE,oBAAoB,EAAE,CAAC;IACrC,mBAAmB,EAAE,WAAW,CAAC;IACjC,cAAc,EAAE,EAAE,EAAE,CAAC;IACrB,0BAA0B,EAAE,KAAK,CAAC,EAAE,EAAE,OAAO,cAAc,CAAC,CAAC;CAC9D,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,gBAAgB;
|
|
1
|
+
{"version":3,"file":"checkpoint-prover.d.ts","sourceRoot":"","sources":["../../src/job/checkpoint-prover.ts"],"names":[],"mappings":"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"}
|