@aztec-labs/prover-client 6.0.0-nightly.20260829
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 +1 -0
- package/dest/config.d.ts +17 -0
- package/dest/config.d.ts.map +1 -0
- package/dest/config.js +63 -0
- package/dest/index.d.ts +4 -0
- package/dest/index.d.ts.map +1 -0
- package/dest/index.js +2 -0
- 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 +58 -0
- package/dest/light/lightweight_checkpoint_builder.d.ts.map +1 -0
- package/dest/light/lightweight_checkpoint_builder.js +243 -0
- package/dest/mocks/fixtures.d.ts +20 -0
- package/dest/mocks/fixtures.d.ts.map +1 -0
- package/dest/mocks/fixtures.js +96 -0
- package/dest/mocks/test_context.d.ts +93 -0
- package/dest/mocks/test_context.d.ts.map +1 -0
- package/dest/mocks/test_context.js +354 -0
- package/dest/orchestrator/block-building-helpers.d.ts +67 -0
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -0
- package/dest/orchestrator/block-building-helpers.js +274 -0
- package/dest/orchestrator/block-proving-state.d.ts +107 -0
- package/dest/orchestrator/block-proving-state.d.ts.map +1 -0
- package/dest/orchestrator/block-proving-state.js +339 -0
- package/dest/orchestrator/checkpoint-proving-state.d.ts +67 -0
- package/dest/orchestrator/checkpoint-proving-state.d.ts.map +1 -0
- package/dest/orchestrator/checkpoint-proving-state.js +175 -0
- package/dest/orchestrator/checkpoint-sub-tree-orchestrator.d.ts +169 -0
- package/dest/orchestrator/checkpoint-sub-tree-orchestrator.d.ts.map +1 -0
- package/dest/orchestrator/checkpoint-sub-tree-orchestrator.js +1047 -0
- package/dest/orchestrator/chonk-cache.d.ts +39 -0
- package/dest/orchestrator/chonk-cache.d.ts.map +1 -0
- package/dest/orchestrator/chonk-cache.js +80 -0
- package/dest/orchestrator/index.d.ts +4 -0
- package/dest/orchestrator/index.d.ts.map +1 -0
- package/dest/orchestrator/index.js +3 -0
- package/dest/orchestrator/orchestrator_metrics.d.ts +8 -0
- package/dest/orchestrator/orchestrator_metrics.d.ts.map +1 -0
- package/dest/orchestrator/orchestrator_metrics.js +13 -0
- package/dest/orchestrator/proving-scheduler.d.ts +81 -0
- package/dest/orchestrator/proving-scheduler.d.ts.map +1 -0
- package/dest/orchestrator/proving-scheduler.js +120 -0
- package/dest/orchestrator/top-tree-orchestrator.d.ts +89 -0
- package/dest/orchestrator/top-tree-orchestrator.d.ts.map +1 -0
- package/dest/orchestrator/top-tree-orchestrator.js +233 -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 +37 -0
- package/dest/orchestrator/tx-proving-state.d.ts.map +1 -0
- package/dest/orchestrator/tx-proving-state.js +77 -0
- package/dest/prover-client/factory.d.ts +6 -0
- package/dest/prover-client/factory.d.ts.map +1 -0
- package/dest/prover-client/factory.js +5 -0
- package/dest/prover-client/index.d.ts +3 -0
- package/dest/prover-client/index.d.ts.map +1 -0
- package/dest/prover-client/index.js +2 -0
- package/dest/prover-client/prover-client.d.ts +99 -0
- package/dest/prover-client/prover-client.d.ts.map +1 -0
- package/dest/prover-client/prover-client.js +163 -0
- package/dest/proving_broker/broker_prover_facade.d.ts +52 -0
- package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -0
- package/dest/proving_broker/broker_prover_facade.js +360 -0
- package/dest/proving_broker/config.d.ts +40 -0
- package/dest/proving_broker/config.d.ts.map +1 -0
- package/dest/proving_broker/config.js +138 -0
- package/dest/proving_broker/factory.d.ts +5 -0
- package/dest/proving_broker/factory.d.ts.map +1 -0
- package/dest/proving_broker/factory.js +13 -0
- package/dest/proving_broker/fixtures.d.ts +6 -0
- package/dest/proving_broker/fixtures.d.ts.map +1 -0
- package/dest/proving_broker/fixtures.js +13 -0
- package/dest/proving_broker/index.d.ts +11 -0
- package/dest/proving_broker/index.d.ts.map +1 -0
- package/dest/proving_broker/index.js +10 -0
- package/dest/proving_broker/proof_store/factory.d.ts +3 -0
- package/dest/proving_broker/proof_store/factory.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/factory.js +13 -0
- 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 +5 -0
- package/dest/proving_broker/proof_store/index.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/index.js +4 -0
- package/dest/proving_broker/proof_store/inline_proof_store.d.ts +15 -0
- package/dest/proving_broker/proof_store/inline_proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/inline_proof_store.js +41 -0
- package/dest/proving_broker/proof_store/proof_store.d.ts +36 -0
- package/dest/proving_broker/proof_store/proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/proof_store.js +3 -0
- package/dest/proving_broker/proving_agent.d.ts +42 -0
- package/dest/proving_broker/proving_agent.d.ts.map +1 -0
- package/dest/proving_broker/proving_agent.js +155 -0
- package/dest/proving_broker/proving_broker.d.ts +77 -0
- package/dest/proving_broker/proving_broker.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker.js +780 -0
- package/dest/proving_broker/proving_broker_database/memory.d.ts +20 -0
- package/dest/proving_broker/proving_broker_database/memory.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker_database/memory.js +67 -0
- package/dest/proving_broker/proving_broker_database/persisted.d.ts +40 -0
- package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker_database/persisted.js +623 -0
- package/dest/proving_broker/proving_broker_database.d.ts +66 -0
- package/dest/proving_broker/proving_broker_database.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker_database.js +3 -0
- package/dest/proving_broker/proving_broker_instrumentation.d.ts +31 -0
- package/dest/proving_broker/proving_broker_instrumentation.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker_instrumentation.js +97 -0
- package/dest/proving_broker/proving_job_controller.d.ts +34 -0
- package/dest/proving_broker/proving_job_controller.d.ts.map +1 -0
- package/dest/proving_broker/proving_job_controller.js +184 -0
- package/dest/proving_broker/rpc.d.ts +38 -0
- package/dest/proving_broker/rpc.d.ts.map +1 -0
- package/dest/proving_broker/rpc.js +138 -0
- package/dest/test/epoch_settlement.d.ts +36 -0
- package/dest/test/epoch_settlement.d.ts.map +1 -0
- package/dest/test/epoch_settlement.js +52 -0
- package/dest/test/index.d.ts +2 -0
- package/dest/test/index.d.ts.map +1 -0
- package/dest/test/index.js +1 -0
- 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 +38 -0
- package/dest/test/mock_prover.d.ts.map +1 -0
- package/dest/test/mock_prover.js +91 -0
- package/package.json +113 -0
- package/src/config.ts +87 -0
- package/src/index.ts +4 -0
- package/src/light/index.ts +1 -0
- package/src/light/lightweight_checkpoint_builder.ts +342 -0
- package/src/mocks/fixtures.ts +120 -0
- package/src/mocks/test_context.ts +477 -0
- package/src/orchestrator/block-building-helpers.ts +486 -0
- package/src/orchestrator/block-proving-state.ts +457 -0
- package/src/orchestrator/checkpoint-proving-state.ts +247 -0
- package/src/orchestrator/checkpoint-sub-tree-orchestrator.ts +1010 -0
- package/src/orchestrator/chonk-cache.ts +99 -0
- package/src/orchestrator/index.ts +12 -0
- package/src/orchestrator/orchestrator_metrics.ts +18 -0
- package/src/orchestrator/proving-scheduler.ts +160 -0
- package/src/orchestrator/top-tree-orchestrator.ts +394 -0
- package/src/orchestrator/top-tree-proving-state.ts +219 -0
- package/src/orchestrator/tx-proving-state.ts +121 -0
- package/src/prover-client/factory.ts +18 -0
- package/src/prover-client/index.ts +2 -0
- package/src/prover-client/prover-client.ts +286 -0
- package/src/proving_broker/broker_prover_facade.ts +626 -0
- package/src/proving_broker/config.ts +178 -0
- package/src/proving_broker/factory.ts +19 -0
- package/src/proving_broker/fixtures.ts +20 -0
- package/src/proving_broker/index.ts +10 -0
- package/src/proving_broker/proof_store/factory.ts +20 -0
- package/src/proving_broker/proof_store/file_store_proof_store.ts +78 -0
- package/src/proving_broker/proof_store/index.ts +4 -0
- package/src/proving_broker/proof_store/inline_proof_store.ts +63 -0
- package/src/proving_broker/proof_store/proof_store.ts +54 -0
- package/src/proving_broker/proving_agent.ts +210 -0
- package/src/proving_broker/proving_broker.ts +888 -0
- package/src/proving_broker/proving_broker_database/memory.ts +78 -0
- package/src/proving_broker/proving_broker_database/persisted.ts +296 -0
- package/src/proving_broker/proving_broker_database.ts +75 -0
- package/src/proving_broker/proving_broker_instrumentation.ts +133 -0
- package/src/proving_broker/proving_job_controller.ts +199 -0
- package/src/proving_broker/rpc.ts +131 -0
- package/src/test/epoch_settlement.ts +82 -0
- package/src/test/index.ts +1 -0
- package/src/test/mock_proof_store.ts +14 -0
- package/src/test/mock_prover.ts +304 -0
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type BlockBlobData,
|
|
3
|
+
type BlockEndBlobData,
|
|
4
|
+
type SpongeBlob,
|
|
5
|
+
encodeBlockEndBlobData,
|
|
6
|
+
} from '@aztec-labs/blob-lib';
|
|
7
|
+
import type {
|
|
8
|
+
ARCHIVE_HEIGHT,
|
|
9
|
+
L1_TO_L2_MSG_TREE_HEIGHT,
|
|
10
|
+
NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
|
|
11
|
+
} from '@aztec-labs/constants';
|
|
12
|
+
import { BlockNumber } from '@aztec-labs/foundation/branded-types';
|
|
13
|
+
import { Fr } from '@aztec-labs/foundation/curves/bn254';
|
|
14
|
+
import type { Tuple } from '@aztec-labs/foundation/serialize';
|
|
15
|
+
import { type TreeNodeLocation, UnbalancedTreeStore } from '@aztec-labs/foundation/trees';
|
|
16
|
+
import type { PublicInputsAndRecursiveProof } from '@aztec-labs/stdlib/interfaces/server';
|
|
17
|
+
import { L1ToL2MessageBundle, type L1ToL2MessageSponge, makeL1ToL2MessageBundle } from '@aztec-labs/stdlib/messaging';
|
|
18
|
+
import {
|
|
19
|
+
BlockRollupPublicInputs,
|
|
20
|
+
BlockRootNoTxsRollupPrivateInputs,
|
|
21
|
+
BlockRootRollupPrivateInputs,
|
|
22
|
+
BlockRootSingleTxRollupPrivateInputs,
|
|
23
|
+
CheckpointConstantData,
|
|
24
|
+
TxMergeRollupPrivateInputs,
|
|
25
|
+
type TxRollupPublicInputs,
|
|
26
|
+
} from '@aztec-labs/stdlib/rollup';
|
|
27
|
+
import type { CircuitName } from '@aztec-labs/stdlib/stats';
|
|
28
|
+
import { AppendOnlyTreeSnapshot } from '@aztec-labs/stdlib/trees';
|
|
29
|
+
import { BlockHeader, GlobalVariables, StateReference } from '@aztec-labs/stdlib/tx';
|
|
30
|
+
import type { UInt64 } from '@aztec-labs/stdlib/types';
|
|
31
|
+
|
|
32
|
+
import { buildHeaderFromCircuitOutputs, toProofData } from './block-building-helpers.js';
|
|
33
|
+
import type { CheckpointProvingState } from './checkpoint-proving-state.js';
|
|
34
|
+
import type { TxProvingState } from './tx-proving-state.js';
|
|
35
|
+
|
|
36
|
+
export type ProofState<T, PROOF_LENGTH extends number> = {
|
|
37
|
+
provingOutput?: PublicInputsAndRecursiveProof<T, PROOF_LENGTH>;
|
|
38
|
+
isProving?: boolean;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The block-root rollup flavor a block proves with and its private inputs, discriminated by circuit name so callers
|
|
43
|
+
* can dispatch to the matching prover entrypoint with the correctly-typed inputs.
|
|
44
|
+
*/
|
|
45
|
+
export type BlockRootRollupTypeAndInputs =
|
|
46
|
+
| { rollupType: 'rollup-block-root-no-txs'; inputs: BlockRootNoTxsRollupPrivateInputs }
|
|
47
|
+
| { rollupType: 'rollup-block-root-single-tx'; inputs: BlockRootSingleTxRollupPrivateInputs }
|
|
48
|
+
| { rollupType: 'rollup-block-root'; inputs: BlockRootRollupPrivateInputs };
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The current state of the proving schedule for a given block. Managed by ProvingState.
|
|
52
|
+
* Contains the raw inputs and intermediate state to generate every constituent proof in the tree.
|
|
53
|
+
*/
|
|
54
|
+
export class BlockProvingState {
|
|
55
|
+
private baseOrMergeProofs: UnbalancedTreeStore<
|
|
56
|
+
ProofState<TxRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
|
|
57
|
+
> = new UnbalancedTreeStore(0);
|
|
58
|
+
private blockRootProof:
|
|
59
|
+
| ProofState<BlockRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
|
|
60
|
+
| undefined;
|
|
61
|
+
private builtBlockHeader: BlockHeader | undefined;
|
|
62
|
+
private builtArchive: AppendOnlyTreeSnapshot | undefined;
|
|
63
|
+
private endState: StateReference | undefined;
|
|
64
|
+
private endSpongeBlob: SpongeBlob | undefined;
|
|
65
|
+
private txs: TxProvingState[] = [];
|
|
66
|
+
private error: string | undefined;
|
|
67
|
+
|
|
68
|
+
constructor(
|
|
69
|
+
public readonly index: number,
|
|
70
|
+
public readonly blockNumber: BlockNumber,
|
|
71
|
+
public readonly totalNumTxs: number,
|
|
72
|
+
private readonly constants: CheckpointConstantData,
|
|
73
|
+
private readonly timestamp: UInt64,
|
|
74
|
+
public readonly lastArchiveTreeSnapshot: AppendOnlyTreeSnapshot,
|
|
75
|
+
private readonly lastArchiveSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>,
|
|
76
|
+
// The full state reference of the previous block, before this block's bundle is appended. Feeds the msgs-only
|
|
77
|
+
// block root, whose zero-tx block has no tx constants to pin the previous state.
|
|
78
|
+
private readonly previousState: StateReference,
|
|
79
|
+
// This block's L1-to-L2 message tree snapshot before and after its own bundle. The start is
|
|
80
|
+
// the previous block's end (block-merge continuity); the end is this block's own post-bundle snapshot.
|
|
81
|
+
private readonly startL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot,
|
|
82
|
+
public readonly newL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot,
|
|
83
|
+
// Full-height frontier (left-sibling path) at the block's start index, pinning the append at a compact index.
|
|
84
|
+
private readonly l1ToL2MessageFrontierHint: Tuple<Fr, typeof L1_TO_L2_MSG_TREE_HEIGHT>,
|
|
85
|
+
// This block's own real L1-to-L2 message leaves (unpadded slice).
|
|
86
|
+
private readonly l1ToL2Messages: Fr[],
|
|
87
|
+
// Message sponge threaded across the checkpoint's blocks: the start is the previous block's
|
|
88
|
+
// end sponge (empty for the first block), the end absorbs this block's own slice. Block merges assert the
|
|
89
|
+
// continuity, so the end is exposed for the next block to inherit.
|
|
90
|
+
private readonly startMsgSponge: L1ToL2MessageSponge,
|
|
91
|
+
private readonly endMsgSponge: L1ToL2MessageSponge,
|
|
92
|
+
private readonly startSpongeBlob: SpongeBlob,
|
|
93
|
+
public parentCheckpoint: CheckpointProvingState,
|
|
94
|
+
) {
|
|
95
|
+
this.baseOrMergeProofs = new UnbalancedTreeStore(totalNumTxs);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** The message sponge after absorbing this block's slice; inherited by the next block as its start sponge. */
|
|
99
|
+
public getEndMsgSponge(): L1ToL2MessageSponge {
|
|
100
|
+
return this.endMsgSponge;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
public get epochNumber(): number {
|
|
104
|
+
return this.parentCheckpoint.epochNumber;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Adds a transaction to the proving state, returns it's index
|
|
108
|
+
public addNewTx(tx: TxProvingState) {
|
|
109
|
+
if (!this.isAcceptingTxs()) {
|
|
110
|
+
throw new Error(`Cannot add more txs to block ${this.blockNumber}.`);
|
|
111
|
+
}
|
|
112
|
+
const txIndex = this.txs.length;
|
|
113
|
+
this.txs[txIndex] = tx;
|
|
114
|
+
return txIndex;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
public isAcceptingTxs() {
|
|
118
|
+
return this.txs.length < this.totalNumTxs;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public getProcessedTxs() {
|
|
122
|
+
return this.txs.map(t => t.processedTx);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public tryStartProvingBase(txIndex: number) {
|
|
126
|
+
if (this.baseOrMergeProofs.getLeaf(txIndex)?.isProving) {
|
|
127
|
+
return false;
|
|
128
|
+
} else {
|
|
129
|
+
this.baseOrMergeProofs.setLeaf(txIndex, { isProving: true });
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
public setBaseRollupProof(
|
|
135
|
+
txIndex: number,
|
|
136
|
+
provingOutput: PublicInputsAndRecursiveProof<
|
|
137
|
+
TxRollupPublicInputs,
|
|
138
|
+
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
139
|
+
>,
|
|
140
|
+
): TreeNodeLocation {
|
|
141
|
+
return this.baseOrMergeProofs.setLeaf(txIndex, { provingOutput });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public tryStartProvingMerge(location: TreeNodeLocation) {
|
|
145
|
+
if (this.baseOrMergeProofs.getNode(location)?.isProving) {
|
|
146
|
+
return false;
|
|
147
|
+
} else {
|
|
148
|
+
this.baseOrMergeProofs.setNode(location, { isProving: true });
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
public setMergeRollupProof(
|
|
154
|
+
location: TreeNodeLocation,
|
|
155
|
+
provingOutput: PublicInputsAndRecursiveProof<
|
|
156
|
+
TxRollupPublicInputs,
|
|
157
|
+
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
158
|
+
>,
|
|
159
|
+
) {
|
|
160
|
+
this.baseOrMergeProofs.setNode(location, { provingOutput });
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
public tryStartProvingBlockRoot() {
|
|
164
|
+
if (this.blockRootProof?.isProving) {
|
|
165
|
+
return false;
|
|
166
|
+
} else {
|
|
167
|
+
this.blockRootProof = { isProving: true };
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
public setBlockRootRollupProof(
|
|
173
|
+
provingOutput: PublicInputsAndRecursiveProof<
|
|
174
|
+
BlockRollupPublicInputs,
|
|
175
|
+
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
176
|
+
>,
|
|
177
|
+
): TreeNodeLocation {
|
|
178
|
+
this.blockRootProof = { provingOutput };
|
|
179
|
+
return this.parentCheckpoint.setBlockRootRollupProof(this.index, provingOutput);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
public getBlockRootRollupOutput() {
|
|
183
|
+
return this.blockRootProof?.provingOutput?.inputs;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
public async buildBlockHeader() {
|
|
187
|
+
if (this.isAcceptingTxs()) {
|
|
188
|
+
throw new Error('All txs must be added to the block before building the header.');
|
|
189
|
+
}
|
|
190
|
+
if (!this.endState) {
|
|
191
|
+
throw new Error('Call `setEndState` first.');
|
|
192
|
+
}
|
|
193
|
+
if (!this.endSpongeBlob) {
|
|
194
|
+
throw new Error('Call `setEndSpongeBlob` first.');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const endSpongeBlob = this.endSpongeBlob.clone();
|
|
198
|
+
const endSpongeBlobHash = await endSpongeBlob.squeeze();
|
|
199
|
+
|
|
200
|
+
this.builtBlockHeader = new BlockHeader(
|
|
201
|
+
this.lastArchiveTreeSnapshot,
|
|
202
|
+
this.endState,
|
|
203
|
+
endSpongeBlobHash,
|
|
204
|
+
this.#getGlobalVariables(),
|
|
205
|
+
this.#getTotalFees(),
|
|
206
|
+
new Fr(this.#getTotalManaUsed()),
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
return this.builtBlockHeader;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
public getBuiltBlockHeader() {
|
|
213
|
+
return this.builtBlockHeader;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
public setBuiltArchive(archive: AppendOnlyTreeSnapshot) {
|
|
217
|
+
this.builtArchive = archive;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
public getBuiltArchive() {
|
|
221
|
+
return this.builtArchive;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
public getStartSpongeBlob() {
|
|
225
|
+
return this.startSpongeBlob;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
public setEndSpongeBlob(endSpongeBlob: SpongeBlob) {
|
|
229
|
+
this.endSpongeBlob = endSpongeBlob;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
public getEndSpongeBlob() {
|
|
233
|
+
return this.endSpongeBlob;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
public setEndState(endState: StateReference) {
|
|
237
|
+
this.endState = endState;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
public hasEndState() {
|
|
241
|
+
return !!this.endState;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
public getBlockEndBlobFields(): Fr[] {
|
|
245
|
+
return encodeBlockEndBlobData(this.getBlockEndBlobData());
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
getBlockEndBlobData(): BlockEndBlobData {
|
|
249
|
+
if (!this.endState) {
|
|
250
|
+
throw new Error('Call `setEndState` first.');
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const partial = this.endState.partial;
|
|
254
|
+
return {
|
|
255
|
+
blockEndMarker: {
|
|
256
|
+
numTxs: this.totalNumTxs,
|
|
257
|
+
timestamp: this.timestamp,
|
|
258
|
+
blockNumber: this.blockNumber,
|
|
259
|
+
},
|
|
260
|
+
blockEndStateField: {
|
|
261
|
+
l1ToL2MessageNextAvailableLeafIndex: this.newL1ToL2MessageTreeSnapshot.nextAvailableLeafIndex,
|
|
262
|
+
noteHashNextAvailableLeafIndex: partial.noteHashTree.nextAvailableLeafIndex,
|
|
263
|
+
nullifierNextAvailableLeafIndex: partial.nullifierTree.nextAvailableLeafIndex,
|
|
264
|
+
publicDataNextAvailableLeafIndex: partial.publicDataTree.nextAvailableLeafIndex,
|
|
265
|
+
totalManaUsed: this.#getTotalManaUsed(),
|
|
266
|
+
},
|
|
267
|
+
lastArchiveRoot: this.lastArchiveTreeSnapshot.root,
|
|
268
|
+
noteHashRoot: partial.noteHashTree.root,
|
|
269
|
+
nullifierRoot: partial.nullifierTree.root,
|
|
270
|
+
publicDataRoot: partial.publicDataTree.root,
|
|
271
|
+
// Every block carries its own post-bundle l1-to-l2 message tree root.
|
|
272
|
+
l1ToL2MessageRoot: this.newL1ToL2MessageTreeSnapshot.root,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
public getBlockBlobData(): BlockBlobData {
|
|
277
|
+
return {
|
|
278
|
+
...this.getBlockEndBlobData(),
|
|
279
|
+
txs: this.getTxEffects().map(t => t.toTxBlobData()),
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
public getTxEffects() {
|
|
284
|
+
return this.txs.map(t => t.processedTx.txEffect);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
public getParentLocation(location: TreeNodeLocation) {
|
|
288
|
+
return this.baseOrMergeProofs.getParentLocation(location);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
public getMergeRollupInputs(mergeLocation: TreeNodeLocation) {
|
|
292
|
+
const [left, right] = this.baseOrMergeProofs.getChildren(mergeLocation).map(c => c?.provingOutput);
|
|
293
|
+
if (!left || !right) {
|
|
294
|
+
throw new Error('At least one child is not ready for the merge rollup.');
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return new TxMergeRollupPrivateInputs([toProofData(left), toProofData(right)]);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* The block root variant is selected by transaction count alone. Whether this is the checkpoint's first block is
|
|
302
|
+
* expressed through the start sponge values it feeds the circuit, which the checkpoint root pins to their initial
|
|
303
|
+
* values for the leftmost block and the block merge pins to the previous block's end values otherwise.
|
|
304
|
+
*/
|
|
305
|
+
public getBlockRootRollupTypeAndInputs(): BlockRootRollupTypeAndInputs {
|
|
306
|
+
const provingOutputs = this.#getChildProvingOutputsForBlockRoot();
|
|
307
|
+
if (!provingOutputs.every(p => !!p)) {
|
|
308
|
+
throw new Error('At least one child is not ready for the block root rollup.');
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const previousRollups = provingOutputs.map(p => toProofData(p));
|
|
312
|
+
|
|
313
|
+
const messageBundle = this.#getMessageBundle();
|
|
314
|
+
const frontierHint = this.#getFrontierHint();
|
|
315
|
+
const startMsgSponge = this.startMsgSponge;
|
|
316
|
+
|
|
317
|
+
const [leftRollup, rightRollup] = previousRollups;
|
|
318
|
+
if (!leftRollup) {
|
|
319
|
+
return {
|
|
320
|
+
rollupType: 'rollup-block-root-no-txs' satisfies CircuitName,
|
|
321
|
+
inputs: new BlockRootNoTxsRollupPrivateInputs(
|
|
322
|
+
this.lastArchiveTreeSnapshot,
|
|
323
|
+
this.previousState,
|
|
324
|
+
this.constants,
|
|
325
|
+
this.timestamp,
|
|
326
|
+
this.startSpongeBlob,
|
|
327
|
+
startMsgSponge,
|
|
328
|
+
messageBundle,
|
|
329
|
+
frontierHint,
|
|
330
|
+
this.lastArchiveSiblingPath,
|
|
331
|
+
),
|
|
332
|
+
};
|
|
333
|
+
} else if (!rightRollup) {
|
|
334
|
+
return {
|
|
335
|
+
rollupType: 'rollup-block-root-single-tx' satisfies CircuitName,
|
|
336
|
+
inputs: new BlockRootSingleTxRollupPrivateInputs(
|
|
337
|
+
leftRollup,
|
|
338
|
+
messageBundle,
|
|
339
|
+
this.startL1ToL2MessageTreeSnapshot,
|
|
340
|
+
startMsgSponge,
|
|
341
|
+
frontierHint,
|
|
342
|
+
this.lastArchiveSiblingPath,
|
|
343
|
+
),
|
|
344
|
+
};
|
|
345
|
+
} else {
|
|
346
|
+
return {
|
|
347
|
+
rollupType: 'rollup-block-root' satisfies CircuitName,
|
|
348
|
+
inputs: new BlockRootRollupPrivateInputs(
|
|
349
|
+
[leftRollup, rightRollup],
|
|
350
|
+
messageBundle,
|
|
351
|
+
this.startL1ToL2MessageTreeSnapshot,
|
|
352
|
+
startMsgSponge,
|
|
353
|
+
frontierHint,
|
|
354
|
+
this.lastArchiveSiblingPath,
|
|
355
|
+
),
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* The real-count message bundle this block appends: the block's own message slice, inserted at
|
|
362
|
+
* compact indices and absorbed into its block-root message sponge.
|
|
363
|
+
*/
|
|
364
|
+
#getMessageBundle(): L1ToL2MessageBundle {
|
|
365
|
+
return this.l1ToL2Messages.length === 0
|
|
366
|
+
? L1ToL2MessageBundle.empty()
|
|
367
|
+
: makeL1ToL2MessageBundle(this.l1ToL2Messages);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Full-height frontier hint for the bundle append: the left-sibling path at the block's compact start index, which
|
|
372
|
+
* the block-root circuit re-hashes against its start snapshot root.
|
|
373
|
+
*/
|
|
374
|
+
#getFrontierHint(): Tuple<Fr, typeof L1_TO_L2_MSG_TREE_HEIGHT> {
|
|
375
|
+
return this.l1ToL2MessageFrontierHint;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// Returns a specific transaction proving state
|
|
379
|
+
public getTxProvingState(txIndex: number) {
|
|
380
|
+
return this.txs[txIndex];
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
public async buildHeaderFromProvingOutputs() {
|
|
384
|
+
if (!this.blockRootProof?.provingOutput) {
|
|
385
|
+
throw new Error('Block root rollup is not ready.');
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
return await buildHeaderFromCircuitOutputs(this.blockRootProof.provingOutput.inputs);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
public isReadyForMergeRollup(location: TreeNodeLocation) {
|
|
392
|
+
return !!this.baseOrMergeProofs.getSibling(location)?.provingOutput;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// Returns true if we have sufficient inputs to execute the block root rollup. Parity no longer gates the block root
|
|
396
|
+
// (it moved to the checkpoint root), so the block root is ready once its child tx proofs land.
|
|
397
|
+
public isReadyForBlockRootRollup() {
|
|
398
|
+
const childProofs = this.#getChildProvingOutputsForBlockRoot();
|
|
399
|
+
return childProofs.every(p => !!p);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
public isComplete() {
|
|
403
|
+
return !!this.blockRootProof;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
public verifyState() {
|
|
407
|
+
return this.parentCheckpoint.verifyState();
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
public getError() {
|
|
411
|
+
return this.error;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
public reject(reason: string) {
|
|
415
|
+
this.error = reason;
|
|
416
|
+
this.parentCheckpoint.reject(reason);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
#getChildProvingOutputsForBlockRoot() {
|
|
420
|
+
if (this.totalNumTxs === 0) {
|
|
421
|
+
return [];
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
const rootLocation = { level: 0, index: 0 };
|
|
425
|
+
// If there's only 1 tx, its base rollup proof will be stored at the root.
|
|
426
|
+
return this.totalNumTxs === 1
|
|
427
|
+
? [this.baseOrMergeProofs.getNode(rootLocation)?.provingOutput]
|
|
428
|
+
: this.baseOrMergeProofs.getChildren(rootLocation).map(c => c?.provingOutput);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
#getGlobalVariables() {
|
|
432
|
+
if (this.txs.length) {
|
|
433
|
+
return this.txs[0].processedTx.globalVariables;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
const constants = this.constants;
|
|
437
|
+
|
|
438
|
+
return GlobalVariables.from({
|
|
439
|
+
chainId: constants.chainId,
|
|
440
|
+
version: constants.version,
|
|
441
|
+
blockNumber: this.blockNumber,
|
|
442
|
+
slotNumber: constants.slotNumber,
|
|
443
|
+
timestamp: this.timestamp,
|
|
444
|
+
coinbase: constants.coinbase,
|
|
445
|
+
feeRecipient: constants.feeRecipient,
|
|
446
|
+
gasFees: constants.gasFees,
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
#getTotalFees() {
|
|
451
|
+
return this.txs.reduce((acc, tx) => acc.add(tx.processedTx.txEffect.transactionFee), Fr.ZERO);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
#getTotalManaUsed() {
|
|
455
|
+
return this.txs.reduce((acc, tx) => acc + BigInt(tx.processedTx.gasUsed.billedGas.l2Gas), 0n);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { SpongeBlob } from '@aztec-labs/blob-lib';
|
|
2
|
+
import type {
|
|
3
|
+
ARCHIVE_HEIGHT,
|
|
4
|
+
L1_TO_L2_MSG_TREE_HEIGHT,
|
|
5
|
+
NESTED_RECURSIVE_PROOF_LENGTH,
|
|
6
|
+
NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
|
|
7
|
+
} from '@aztec-labs/constants';
|
|
8
|
+
import { BlockNumber } from '@aztec-labs/foundation/branded-types';
|
|
9
|
+
import { Fr } from '@aztec-labs/foundation/curves/bn254';
|
|
10
|
+
import type { Tuple } from '@aztec-labs/foundation/serialize';
|
|
11
|
+
import { type TreeNodeLocation, UnbalancedTreeStore } from '@aztec-labs/foundation/trees';
|
|
12
|
+
import type { PublicInputsAndRecursiveProof } from '@aztec-labs/stdlib/interfaces/server';
|
|
13
|
+
import { L1ToL2MessageSponge } from '@aztec-labs/stdlib/messaging';
|
|
14
|
+
import { InboxParityPrivateInputs, type ParityPublicInputs } from '@aztec-labs/stdlib/parity';
|
|
15
|
+
import {
|
|
16
|
+
BlockMergeRollupPrivateInputs,
|
|
17
|
+
BlockRollupPublicInputs,
|
|
18
|
+
CheckpointConstantData,
|
|
19
|
+
} from '@aztec-labs/stdlib/rollup';
|
|
20
|
+
import type { AppendOnlyTreeSnapshot } from '@aztec-labs/stdlib/trees';
|
|
21
|
+
import type { BlockHeader, StateReference } from '@aztec-labs/stdlib/tx';
|
|
22
|
+
import type { UInt64 } from '@aztec-labs/stdlib/types';
|
|
23
|
+
|
|
24
|
+
import { toProofData } from './block-building-helpers.js';
|
|
25
|
+
import { BlockProvingState, type ProofState } from './block-proving-state.js';
|
|
26
|
+
|
|
27
|
+
export class CheckpointProvingState {
|
|
28
|
+
private blockProofs: UnbalancedTreeStore<
|
|
29
|
+
ProofState<BlockRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
|
|
30
|
+
>;
|
|
31
|
+
// The checkpoint's single InboxParity proof. Parity gates the checkpoint root, not the first block root: one
|
|
32
|
+
// variable-size proof per checkpoint replaces the former base + root parity fan-in. Surfaced as part of the
|
|
33
|
+
// sub-tree result.
|
|
34
|
+
private inboxParityProof: ProofState<ParityPublicInputs, typeof NESTED_RECURSIVE_PROOF_LENGTH> | undefined;
|
|
35
|
+
private blocks: (BlockProvingState | undefined)[] = [];
|
|
36
|
+
private error: string | undefined;
|
|
37
|
+
public readonly firstBlockNumber: BlockNumber;
|
|
38
|
+
|
|
39
|
+
constructor(
|
|
40
|
+
public readonly index: number,
|
|
41
|
+
public readonly constants: CheckpointConstantData,
|
|
42
|
+
public readonly totalNumBlocks: number,
|
|
43
|
+
private readonly headerOfLastBlockInPreviousCheckpoint: BlockHeader,
|
|
44
|
+
private readonly lastArchiveSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>,
|
|
45
|
+
private readonly l1ToL2Messages: Fr[],
|
|
46
|
+
// Inbox rolling hash before this checkpoint's messages (the previous checkpoint's end value; genesis is zero).
|
|
47
|
+
// Threaded into the InboxParity circuit so the resulting checkpoint header rolling hash matches the proposer's.
|
|
48
|
+
private readonly startInboxRollingHash: Fr,
|
|
49
|
+
public readonly epochNumber: number,
|
|
50
|
+
/** Owner's liveness check. `verifyState()` returns false once this returns false. */
|
|
51
|
+
private readonly isAlive: () => boolean,
|
|
52
|
+
/** Owner's failure callback. Invoked from `reject` to surface the error upward. */
|
|
53
|
+
private readonly onReject: (reason: string) => void,
|
|
54
|
+
) {
|
|
55
|
+
this.blockProofs = new UnbalancedTreeStore(totalNumBlocks);
|
|
56
|
+
this.firstBlockNumber = BlockNumber(headerOfLastBlockInPreviousCheckpoint.globalVariables.blockNumber + 1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** The checkpoint's real L1-to-L2 messages (unpadded), consumed across its blocks. */
|
|
60
|
+
public getL1ToL2Messages(): Fr[] {
|
|
61
|
+
return this.l1ToL2Messages;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public async startNewBlock(
|
|
65
|
+
blockNumber: BlockNumber,
|
|
66
|
+
timestamp: UInt64,
|
|
67
|
+
totalNumTxs: number,
|
|
68
|
+
lastArchiveTreeSnapshot: AppendOnlyTreeSnapshot,
|
|
69
|
+
lastArchiveSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>,
|
|
70
|
+
// The full state reference of the previous block (before this block's message bundle is appended). Feeds the
|
|
71
|
+
// msgs-only block root, whose zero-tx block carries no tx constants to pin the previous state.
|
|
72
|
+
previousState: StateReference,
|
|
73
|
+
// Per-block L1-to-L2 message state: the block's start snapshot (its parent's end), its own
|
|
74
|
+
// post-bundle end snapshot, the full-height frontier at the start index, and its own real message slice.
|
|
75
|
+
startL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot,
|
|
76
|
+
endL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot,
|
|
77
|
+
l1ToL2MessageFrontierHint: Tuple<Fr, typeof L1_TO_L2_MSG_TREE_HEIGHT>,
|
|
78
|
+
l1ToL2Messages: Fr[],
|
|
79
|
+
): Promise<BlockProvingState> {
|
|
80
|
+
const index = Number(blockNumber) - Number(this.firstBlockNumber);
|
|
81
|
+
if (index >= this.totalNumBlocks) {
|
|
82
|
+
throw new Error(`Unable to start a new block at index ${index}. Expected at most ${this.totalNumBlocks} blocks.`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const startSpongeBlob = index === 0 ? SpongeBlob.init() : this.blocks[index - 1]?.getEndSpongeBlob();
|
|
86
|
+
if (!startSpongeBlob) {
|
|
87
|
+
throw new Error(
|
|
88
|
+
'Cannot start a new block before the trees have progressed from the tx effects in the previous block.',
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Thread the message sponge across the checkpoint's blocks: each block starts from the
|
|
93
|
+
// previous block's end sponge (empty for the first block) and absorbs its own real slice. The block merge and
|
|
94
|
+
// checkpoint root circuits assert exactly this continuity (`right.start_msg_sponge == left.end_msg_sponge`, first
|
|
95
|
+
// block starts empty, merged end equals the InboxParity sponge), so the end sponge is computed eagerly here for
|
|
96
|
+
// the next block to inherit. Blocks must therefore be started in order, which the sequential per-block message
|
|
97
|
+
// appends already require.
|
|
98
|
+
const startMsgSponge = index === 0 ? L1ToL2MessageSponge.empty() : this.blocks[index - 1]?.getEndMsgSponge();
|
|
99
|
+
if (!startMsgSponge) {
|
|
100
|
+
throw new Error('Cannot start a new block before the previous block in the checkpoint has been started.');
|
|
101
|
+
}
|
|
102
|
+
const endMsgSponge = startMsgSponge.clone();
|
|
103
|
+
await endMsgSponge.absorb(l1ToL2Messages);
|
|
104
|
+
|
|
105
|
+
const block = new BlockProvingState(
|
|
106
|
+
index,
|
|
107
|
+
blockNumber,
|
|
108
|
+
totalNumTxs,
|
|
109
|
+
this.constants,
|
|
110
|
+
timestamp,
|
|
111
|
+
lastArchiveTreeSnapshot,
|
|
112
|
+
lastArchiveSiblingPath,
|
|
113
|
+
previousState,
|
|
114
|
+
startL1ToL2MessageTreeSnapshot,
|
|
115
|
+
endL1ToL2MessageTreeSnapshot,
|
|
116
|
+
l1ToL2MessageFrontierHint,
|
|
117
|
+
l1ToL2Messages,
|
|
118
|
+
startMsgSponge,
|
|
119
|
+
endMsgSponge,
|
|
120
|
+
startSpongeBlob,
|
|
121
|
+
this,
|
|
122
|
+
);
|
|
123
|
+
this.blocks[index] = block;
|
|
124
|
+
|
|
125
|
+
return block;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Returns true if we are still able to accept blocks, false otherwise.
|
|
129
|
+
public isAcceptingBlocks() {
|
|
130
|
+
return this.blocks.filter(b => !!b).length < this.totalNumBlocks;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
public setBlockRootRollupProof(
|
|
134
|
+
blockIndex: number,
|
|
135
|
+
provingOutput: PublicInputsAndRecursiveProof<
|
|
136
|
+
BlockRollupPublicInputs,
|
|
137
|
+
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
138
|
+
>,
|
|
139
|
+
): TreeNodeLocation {
|
|
140
|
+
return this.blockProofs.setLeaf(blockIndex, { provingOutput });
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
public tryStartProvingBlockMerge(location: TreeNodeLocation) {
|
|
144
|
+
if (this.blockProofs.getNode(location)?.isProving) {
|
|
145
|
+
return false;
|
|
146
|
+
} else {
|
|
147
|
+
this.blockProofs.setNode(location, { isProving: true });
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
public setBlockMergeRollupProof(
|
|
153
|
+
location: TreeNodeLocation,
|
|
154
|
+
provingOutput: PublicInputsAndRecursiveProof<
|
|
155
|
+
BlockRollupPublicInputs,
|
|
156
|
+
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
157
|
+
>,
|
|
158
|
+
) {
|
|
159
|
+
this.blockProofs.setNode(location, { provingOutput });
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// ---------------- inbox parity proof orchestration ----------------
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Builds the checkpoint's single InboxParity input. The circuit is sized to the smallest ladder rung that fits the
|
|
166
|
+
* message count and the rolling hash starts from the previous checkpoint's end.
|
|
167
|
+
*/
|
|
168
|
+
public getInboxParityInputs(): InboxParityPrivateInputs {
|
|
169
|
+
return InboxParityPrivateInputs.fromMessages(
|
|
170
|
+
this.l1ToL2Messages,
|
|
171
|
+
this.startInboxRollingHash,
|
|
172
|
+
this.constants.proverId,
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
public tryStartProvingInboxParity() {
|
|
177
|
+
if (this.inboxParityProof?.isProving) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
this.inboxParityProof = { isProving: true };
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
public setInboxParityProof(provingOutput: PublicInputsAndRecursiveProof<ParityPublicInputs>) {
|
|
185
|
+
this.inboxParityProof = { provingOutput };
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
public getInboxParityProof() {
|
|
189
|
+
return this.inboxParityProof?.provingOutput;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
public getParentLocation(location: TreeNodeLocation) {
|
|
193
|
+
return this.blockProofs.getParentLocation(location);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
public getBlockMergeRollupInputs(mergeLocation: TreeNodeLocation) {
|
|
197
|
+
const [left, right] = this.blockProofs.getChildren(mergeLocation).map(c => c?.provingOutput);
|
|
198
|
+
if (!left || !right) {
|
|
199
|
+
throw new Error('At least one child is not ready for the block merge rollup.');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return new BlockMergeRollupPrivateInputs([toProofData(left), toProofData(right)]);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
public getBlockProvingStateByBlockNumber(blockNumber: BlockNumber) {
|
|
206
|
+
const index = Number(blockNumber) - Number(this.firstBlockNumber);
|
|
207
|
+
return this.blocks[index];
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
public isReadyForBlockMerge(location: TreeNodeLocation) {
|
|
211
|
+
return !!this.blockProofs.getSibling(location)?.provingOutput;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
public verifyState() {
|
|
215
|
+
return this.isAlive();
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
public getError() {
|
|
219
|
+
return this.error;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Attempts to reject the proving state promise with a reason of 'cancelled'
|
|
223
|
+
public cancel() {
|
|
224
|
+
this.reject('Proving cancelled');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
public reject(reason: string) {
|
|
228
|
+
this.error = reason;
|
|
229
|
+
this.onReject(reason);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Returns the block-level proof outputs that feed into the checkpoint root rollup.
|
|
234
|
+
* Used by `CheckpointSubTreeOrchestrator` to surface its sub-tree result.
|
|
235
|
+
*/
|
|
236
|
+
public getSubTreeOutputProofs() {
|
|
237
|
+
const rootLocation = { level: 0, index: 0 };
|
|
238
|
+
return this.totalNumBlocks === 1
|
|
239
|
+
? [this.blockProofs.getNode(rootLocation)?.provingOutput] // If there's only 1 block, its proof will be stored at the root.
|
|
240
|
+
: this.blockProofs.getChildren(rootLocation).map(c => c?.provingOutput);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** Sibling path of the archive tree captured before any block in this checkpoint landed. */
|
|
244
|
+
public getLastArchiveSiblingPath() {
|
|
245
|
+
return this.lastArchiveSiblingPath;
|
|
246
|
+
}
|
|
247
|
+
}
|