@aztec/sequencer-client 0.26.3 → 0.26.6
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/block_builder/solo_block_builder.d.ts +5 -4
- package/dest/block_builder/solo_block_builder.d.ts.map +1 -1
- package/dest/block_builder/solo_block_builder.js +82 -34
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +29 -3
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +4 -2
- package/dest/index.d.ts +9 -7
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +9 -8
- package/dest/publisher/l1-publisher.js +5 -5
- package/dest/publisher/viem-tx-sender.js +2 -2
- package/dest/sequencer/abstract_phase_manager.d.ts +12 -15
- package/dest/sequencer/abstract_phase_manager.d.ts.map +1 -1
- package/dest/sequencer/abstract_phase_manager.js +32 -24
- package/dest/sequencer/app_logic_phase_manager.d.ts +1 -6
- package/dest/sequencer/app_logic_phase_manager.d.ts.map +1 -1
- package/dest/sequencer/app_logic_phase_manager.js +11 -8
- package/dest/sequencer/hints_builder.d.ts +13 -0
- package/dest/sequencer/hints_builder.d.ts.map +1 -0
- package/dest/sequencer/hints_builder.js +21 -0
- package/dest/sequencer/index.d.ts +1 -1
- package/dest/sequencer/index.d.ts.map +1 -1
- package/dest/sequencer/index.js +2 -2
- package/dest/sequencer/phase_manager_factory.d.ts.map +1 -1
- package/dest/sequencer/phase_manager_factory.js +5 -1
- package/dest/sequencer/processed_tx.d.ts +37 -2
- package/dest/sequencer/processed_tx.d.ts.map +1 -1
- package/dest/sequencer/processed_tx.js +67 -9
- package/dest/sequencer/public_processor.d.ts +3 -1
- package/dest/sequencer/public_processor.d.ts.map +1 -1
- package/dest/sequencer/public_processor.js +18 -11
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +3 -4
- package/dest/sequencer/setup_phase_manager.d.ts +1 -6
- package/dest/sequencer/setup_phase_manager.d.ts.map +1 -1
- package/dest/sequencer/setup_phase_manager.js +3 -5
- package/dest/sequencer/tail_phase_manager.d.ts +28 -0
- package/dest/sequencer/tail_phase_manager.d.ts.map +1 -0
- package/dest/sequencer/tail_phase_manager.js +32 -0
- package/dest/sequencer/teardown_phase_manager.d.ts +1 -6
- package/dest/sequencer/teardown_phase_manager.d.ts.map +1 -1
- package/dest/sequencer/teardown_phase_manager.js +3 -4
- package/dest/simulator/acvm_native.d.ts +20 -0
- package/dest/simulator/acvm_native.d.ts.map +1 -0
- package/dest/simulator/acvm_native.js +96 -0
- package/dest/simulator/acvm_wasm.d.ts +7 -0
- package/dest/simulator/acvm_wasm.d.ts.map +1 -0
- package/dest/simulator/acvm_wasm.js +23 -0
- package/dest/simulator/index.d.ts +8 -1
- package/dest/simulator/index.d.ts.map +1 -1
- package/dest/simulator/index.js +2 -2
- package/dest/simulator/public_kernel.d.ts +11 -1
- package/dest/simulator/public_kernel.d.ts.map +1 -1
- package/dest/simulator/public_kernel.js +34 -6
- package/dest/simulator/rollup.d.ts +4 -0
- package/dest/simulator/rollup.d.ts.map +1 -1
- package/dest/simulator/rollup.js +16 -20
- package/dest/simulator/simulation_provider.d.ts +9 -0
- package/dest/simulator/simulation_provider.d.ts.map +1 -0
- package/dest/simulator/simulation_provider.js +2 -0
- package/package.json +15 -13
- package/src/block_builder/solo_block_builder.ts +115 -82
- package/src/client/sequencer-client.ts +37 -2
- package/src/config.ts +4 -0
- package/src/index.ts +9 -7
- package/src/publisher/l1-publisher.ts +4 -4
- package/src/publisher/viem-tx-sender.ts +1 -1
- package/src/sequencer/abstract_phase_manager.ts +58 -48
- package/src/sequencer/app_logic_phase_manager.ts +12 -22
- package/src/sequencer/hints_builder.ts +56 -0
- package/src/sequencer/index.ts +1 -1
- package/src/sequencer/phase_manager_factory.ts +12 -0
- package/src/sequencer/processed_tx.ts +147 -17
- package/src/sequencer/public_processor.ts +28 -14
- package/src/sequencer/sequencer.ts +2 -3
- package/src/sequencer/setup_phase_manager.ts +5 -19
- package/src/sequencer/tail_phase_manager.ts +49 -0
- package/src/sequencer/teardown_phase_manager.ts +5 -18
- package/src/simulator/acvm_native.ts +112 -0
- package/src/simulator/acvm_wasm.ts +31 -0
- package/src/simulator/index.ts +8 -0
- package/src/simulator/public_kernel.ts +62 -8
- package/src/simulator/rollup.ts +31 -19
- package/src/simulator/simulation_provider.ts +10 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Body,
|
|
1
|
+
import { Body, L2Block, MerkleTreeId, TxEffect } from '@aztec/circuit-types';
|
|
2
|
+
import { CircuitSimulationStats } from '@aztec/circuit-types/stats';
|
|
2
3
|
import {
|
|
3
4
|
ARCHIVE_HEIGHT,
|
|
4
5
|
AppendOnlyTreeSnapshot,
|
|
@@ -6,13 +7,10 @@ import {
|
|
|
6
7
|
BaseRollupInputs,
|
|
7
8
|
CONTRACT_SUBTREE_HEIGHT,
|
|
8
9
|
CONTRACT_SUBTREE_SIBLING_PATH_LENGTH,
|
|
9
|
-
CombinedAccumulatedData,
|
|
10
10
|
ConstantRollupData,
|
|
11
11
|
GlobalVariables,
|
|
12
12
|
L1_TO_L2_MSG_SUBTREE_HEIGHT,
|
|
13
13
|
L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH,
|
|
14
|
-
MAX_NEW_CONTRACTS_PER_TX,
|
|
15
|
-
MAX_NEW_NOTE_HASHES_PER_TX,
|
|
16
14
|
MAX_NEW_NULLIFIERS_PER_TX,
|
|
17
15
|
MAX_PUBLIC_DATA_READS_PER_TX,
|
|
18
16
|
MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
@@ -39,8 +37,6 @@ import {
|
|
|
39
37
|
RollupTypes,
|
|
40
38
|
RootRollupInputs,
|
|
41
39
|
RootRollupPublicInputs,
|
|
42
|
-
SideEffect,
|
|
43
|
-
SideEffectLinkedToNoteHash,
|
|
44
40
|
StateDiffHints,
|
|
45
41
|
StateReference,
|
|
46
42
|
VK_TREE_HEIGHT,
|
|
@@ -52,13 +48,15 @@ import { padArrayEnd } from '@aztec/foundation/collection';
|
|
|
52
48
|
import { Fr } from '@aztec/foundation/fields';
|
|
53
49
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
54
50
|
import { Tuple, assertLength, toFriendlyJSON } from '@aztec/foundation/serialize';
|
|
51
|
+
import { elapsed } from '@aztec/foundation/timer';
|
|
55
52
|
import { MerkleTreeOperations } from '@aztec/world-state';
|
|
56
53
|
|
|
57
54
|
import chunk from 'lodash.chunk';
|
|
55
|
+
import { inspect } from 'util';
|
|
58
56
|
|
|
59
57
|
import { VerificationKeys } from '../mocks/verification_keys.js';
|
|
60
58
|
import { RollupProver } from '../prover/index.js';
|
|
61
|
-
import { ProcessedTx } from '../sequencer/processed_tx.js';
|
|
59
|
+
import { ProcessedTx, toTxEffect } from '../sequencer/processed_tx.js';
|
|
62
60
|
import { RollupSimulator } from '../simulator/index.js';
|
|
63
61
|
import { BlockBuilder } from './index.js';
|
|
64
62
|
import { TreeNames } from './types.js';
|
|
@@ -105,30 +103,7 @@ export class SoloBlockBuilder implements BlockBuilder {
|
|
|
105
103
|
const [circuitsOutput, proof] = await this.runCircuits(globalVariables, txs, newL1ToL2Messages);
|
|
106
104
|
|
|
107
105
|
// Collect all new nullifiers, commitments, and contracts from all txs in this block
|
|
108
|
-
const txEffects: TxEffect[] = txs.map(
|
|
109
|
-
tx =>
|
|
110
|
-
new TxEffect(
|
|
111
|
-
tx.data.combinedData.newNoteHashes.map((c: SideEffect) => c.value) as Tuple<
|
|
112
|
-
Fr,
|
|
113
|
-
typeof MAX_NEW_NOTE_HASHES_PER_TX
|
|
114
|
-
>,
|
|
115
|
-
tx.data.combinedData.newNullifiers.map((n: SideEffectLinkedToNoteHash) => n.value) as Tuple<
|
|
116
|
-
Fr,
|
|
117
|
-
typeof MAX_NEW_NULLIFIERS_PER_TX
|
|
118
|
-
>,
|
|
119
|
-
tx.data.combinedData.newL2ToL1Msgs,
|
|
120
|
-
tx.data.combinedData.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)) as Tuple<
|
|
121
|
-
PublicDataWrite,
|
|
122
|
-
typeof MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX
|
|
123
|
-
>,
|
|
124
|
-
tx.data.combinedData.newContracts.map(cd => cd.hash()) as Tuple<Fr, typeof MAX_NEW_CONTRACTS_PER_TX>,
|
|
125
|
-
tx.data.combinedData.newContracts.map(
|
|
126
|
-
cd => new ContractData(cd.contractAddress, cd.portalContractAddress),
|
|
127
|
-
) as Tuple<ContractData, typeof MAX_NEW_CONTRACTS_PER_TX>,
|
|
128
|
-
tx.encryptedLogs || new TxL2Logs([]),
|
|
129
|
-
tx.unencryptedLogs || new TxL2Logs([]),
|
|
130
|
-
),
|
|
131
|
-
);
|
|
106
|
+
const txEffects: TxEffect[] = txs.map(tx => toTxEffect(tx));
|
|
132
107
|
|
|
133
108
|
const blockBody = new Body(padArrayEnd(newL1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP), txEffects);
|
|
134
109
|
|
|
@@ -138,11 +113,12 @@ export class SoloBlockBuilder implements BlockBuilder {
|
|
|
138
113
|
body: blockBody,
|
|
139
114
|
});
|
|
140
115
|
|
|
141
|
-
if (!l2Block.body.
|
|
116
|
+
if (!l2Block.body.getTxsEffectsHash().equals(circuitsOutput.header.contentCommitment.txsEffectsHash)) {
|
|
117
|
+
this.debug(inspect(blockBody));
|
|
142
118
|
throw new Error(
|
|
143
|
-
`
|
|
144
|
-
.
|
|
145
|
-
.toString('hex')} == ${circuitsOutput.header.contentCommitment.
|
|
119
|
+
`Txs effects hash mismatch, ${l2Block.body
|
|
120
|
+
.getTxsEffectsHash()
|
|
121
|
+
.toString('hex')} == ${circuitsOutput.header.contentCommitment.txsEffectsHash.toString('hex')} `,
|
|
146
122
|
);
|
|
147
123
|
}
|
|
148
124
|
|
|
@@ -189,22 +165,66 @@ export class SoloBlockBuilder implements BlockBuilder {
|
|
|
189
165
|
// padArrayEnd throws if the array is already full. Otherwise it pads till we reach the required size
|
|
190
166
|
const newL1ToL2MessagesTuple = padArrayEnd(newL1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
191
167
|
|
|
192
|
-
//
|
|
193
|
-
const
|
|
168
|
+
// Perform all tree insertions and retrieve snapshots for all base rollups
|
|
169
|
+
const baseRollupInputs: BaseRollupInputs[] = [];
|
|
170
|
+
const treeSnapshots: Map<MerkleTreeId, AppendOnlyTreeSnapshot>[] = [];
|
|
194
171
|
for (const tx of txs) {
|
|
195
|
-
|
|
172
|
+
const input = await this.buildBaseRollupInput(tx, globalVariables);
|
|
173
|
+
baseRollupInputs.push(input);
|
|
174
|
+
const promises = [
|
|
175
|
+
MerkleTreeId.NOTE_HASH_TREE,
|
|
176
|
+
MerkleTreeId.CONTRACT_TREE,
|
|
177
|
+
MerkleTreeId.NULLIFIER_TREE,
|
|
178
|
+
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
179
|
+
].map(async (id: MerkleTreeId) => {
|
|
180
|
+
return { key: id, value: await this.getTreeSnapshot(id) };
|
|
181
|
+
});
|
|
182
|
+
const snapshots: Map<MerkleTreeId, AppendOnlyTreeSnapshot> = new Map(
|
|
183
|
+
(await Promise.all(promises)).map(obj => [obj.key, obj.value]),
|
|
184
|
+
);
|
|
185
|
+
treeSnapshots.push(snapshots);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Run the base rollup circuits for the txs in parallel
|
|
189
|
+
const baseRollupOutputs: Promise<[BaseOrMergeRollupPublicInputs, Proof]>[] = [];
|
|
190
|
+
for (let i = 0; i < txs.length; i++) {
|
|
191
|
+
baseRollupOutputs.push(this.baseRollupCircuit(txs[i], baseRollupInputs[i], treeSnapshots[i]));
|
|
196
192
|
}
|
|
197
193
|
|
|
198
194
|
// Run merge rollups in layers until we have only two outputs
|
|
199
|
-
|
|
200
|
-
|
|
195
|
+
// All merge circuits for each layer are simulated in parallel
|
|
196
|
+
const [duration, mergeInputs] = await elapsed(() => Promise.all(baseRollupOutputs));
|
|
197
|
+
for (let i = 0; i < mergeInputs.length; i++) {
|
|
198
|
+
this.debug(`Simulated base rollup circuit`, {
|
|
199
|
+
eventName: 'circuit-simulation',
|
|
200
|
+
circuitName: 'base-rollup',
|
|
201
|
+
duration: duration / mergeInputs.length,
|
|
202
|
+
inputSize: baseRollupInputs[i].toBuffer().length,
|
|
203
|
+
outputSize: mergeInputs[i][0].toBuffer().length,
|
|
204
|
+
} satisfies CircuitSimulationStats);
|
|
205
|
+
}
|
|
206
|
+
let mergeRollupInputs: [BaseOrMergeRollupPublicInputs, Proof][] = mergeInputs;
|
|
201
207
|
while (mergeRollupInputs.length > 2) {
|
|
208
|
+
const mergeInputStructs: MergeRollupInputs[] = [];
|
|
202
209
|
for (const pair of chunk(mergeRollupInputs, 2)) {
|
|
203
210
|
const [r1, r2] = pair;
|
|
204
|
-
|
|
211
|
+
mergeInputStructs.push(this.createMergeRollupInputs(r1, r2));
|
|
205
212
|
}
|
|
206
|
-
|
|
207
|
-
|
|
213
|
+
|
|
214
|
+
const [duration, mergeOutputs] = await elapsed(() =>
|
|
215
|
+
Promise.all(mergeInputStructs.map(async input => await this.mergeRollupCircuit(input))),
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
for (let i = 0; i < mergeOutputs.length; i++) {
|
|
219
|
+
this.debug(`Simulated merge rollup circuit`, {
|
|
220
|
+
eventName: 'circuit-simulation',
|
|
221
|
+
circuitName: 'merge-rollup',
|
|
222
|
+
duration: duration / mergeOutputs.length,
|
|
223
|
+
inputSize: mergeInputStructs[i].toBuffer().length,
|
|
224
|
+
outputSize: mergeOutputs[i][0].toBuffer().length,
|
|
225
|
+
} satisfies CircuitSimulationStats);
|
|
226
|
+
}
|
|
227
|
+
mergeRollupInputs = mergeOutputs;
|
|
208
228
|
}
|
|
209
229
|
|
|
210
230
|
// Run the root rollup with the last two merge rollups (or base, if no merge layers)
|
|
@@ -214,26 +234,29 @@ export class SoloBlockBuilder implements BlockBuilder {
|
|
|
214
234
|
|
|
215
235
|
protected async baseRollupCircuit(
|
|
216
236
|
tx: ProcessedTx,
|
|
217
|
-
|
|
237
|
+
inputs: BaseRollupInputs,
|
|
238
|
+
treeSnapshots: Map<MerkleTreeId, AppendOnlyTreeSnapshot>,
|
|
218
239
|
): Promise<[BaseOrMergeRollupPublicInputs, Proof]> {
|
|
219
240
|
this.debug(`Running base rollup for ${tx.hash}`);
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
await this.
|
|
223
|
-
const proof = await this.prover.getBaseRollupProof(rollupInput, rollupOutput);
|
|
241
|
+
const rollupOutput = await this.simulator.baseRollupCircuit(inputs);
|
|
242
|
+
this.validatePartialState(rollupOutput.end, treeSnapshots);
|
|
243
|
+
const proof = await this.prover.getBaseRollupProof(inputs, rollupOutput);
|
|
224
244
|
return [rollupOutput, proof];
|
|
225
245
|
}
|
|
226
246
|
|
|
227
|
-
protected
|
|
247
|
+
protected createMergeRollupInputs(
|
|
228
248
|
left: [BaseOrMergeRollupPublicInputs, Proof],
|
|
229
249
|
right: [BaseOrMergeRollupPublicInputs, Proof],
|
|
230
|
-
)
|
|
250
|
+
) {
|
|
231
251
|
const vk = this.getVerificationKey(left[0].rollupType);
|
|
232
252
|
const mergeInputs = new MergeRollupInputs([
|
|
233
253
|
this.getPreviousRollupDataFromPublicInputs(left[0], left[1], vk),
|
|
234
254
|
this.getPreviousRollupDataFromPublicInputs(right[0], right[1], vk),
|
|
235
255
|
]);
|
|
256
|
+
return mergeInputs;
|
|
257
|
+
}
|
|
236
258
|
|
|
259
|
+
protected async mergeRollupCircuit(mergeInputs: MergeRollupInputs): Promise<[BaseOrMergeRollupPublicInputs, Proof]> {
|
|
237
260
|
this.debug(`Running merge rollup circuit`);
|
|
238
261
|
const output = await this.simulator.mergeRollupCircuit(mergeInputs);
|
|
239
262
|
const proof = await this.prover.getMergeRollupProof(mergeInputs, output);
|
|
@@ -279,40 +302,50 @@ export class SoloBlockBuilder implements BlockBuilder {
|
|
|
279
302
|
return [rootOutput, rootProof];
|
|
280
303
|
}
|
|
281
304
|
|
|
282
|
-
protected
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
+
protected validatePartialState(
|
|
306
|
+
partialState: PartialStateReference,
|
|
307
|
+
treeSnapshots: Map<MerkleTreeId, AppendOnlyTreeSnapshot>,
|
|
308
|
+
) {
|
|
309
|
+
this.validateSimulatedTree(
|
|
310
|
+
treeSnapshots.get(MerkleTreeId.NOTE_HASH_TREE)!,
|
|
311
|
+
partialState.noteHashTree,
|
|
312
|
+
'NoteHashTree',
|
|
313
|
+
);
|
|
314
|
+
this.validateSimulatedTree(
|
|
315
|
+
treeSnapshots.get(MerkleTreeId.NULLIFIER_TREE)!,
|
|
316
|
+
partialState.nullifierTree,
|
|
317
|
+
'NullifierTree',
|
|
318
|
+
);
|
|
319
|
+
this.validateSimulatedTree(
|
|
320
|
+
treeSnapshots.get(MerkleTreeId.CONTRACT_TREE)!,
|
|
321
|
+
partialState.contractTree,
|
|
322
|
+
'ContractTree',
|
|
323
|
+
);
|
|
324
|
+
this.validateSimulatedTree(
|
|
325
|
+
treeSnapshots.get(MerkleTreeId.PUBLIC_DATA_TREE)!,
|
|
326
|
+
partialState.publicDataTree,
|
|
327
|
+
'PublicDataTree',
|
|
328
|
+
);
|
|
305
329
|
}
|
|
306
330
|
|
|
307
331
|
protected async validateState(state: StateReference) {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
this.
|
|
315
|
-
|
|
332
|
+
const promises = [
|
|
333
|
+
MerkleTreeId.NOTE_HASH_TREE,
|
|
334
|
+
MerkleTreeId.CONTRACT_TREE,
|
|
335
|
+
MerkleTreeId.NULLIFIER_TREE,
|
|
336
|
+
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
337
|
+
].map(async (id: MerkleTreeId) => {
|
|
338
|
+
return { key: id, value: await this.getTreeSnapshot(id) };
|
|
339
|
+
});
|
|
340
|
+
const snapshots: Map<MerkleTreeId, AppendOnlyTreeSnapshot> = new Map(
|
|
341
|
+
(await Promise.all(promises)).map(obj => [obj.key, obj.value]),
|
|
342
|
+
);
|
|
343
|
+
this.validatePartialState(state.partial, snapshots);
|
|
344
|
+
this.validateSimulatedTree(
|
|
345
|
+
await this.getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE),
|
|
346
|
+
state.l1ToL2MessageTree,
|
|
347
|
+
'L1ToL2MessageTree',
|
|
348
|
+
);
|
|
316
349
|
}
|
|
317
350
|
|
|
318
351
|
// Validate that the roots of all local trees match the output of the root circuit simulation
|
|
@@ -420,7 +453,7 @@ export class SoloBlockBuilder implements BlockBuilder {
|
|
|
420
453
|
protected getKernelDataFor(tx: ProcessedTx): RollupKernelData {
|
|
421
454
|
const inputs = new RollupKernelCircuitPublicInputs(
|
|
422
455
|
tx.data.aggregationObject,
|
|
423
|
-
|
|
456
|
+
tx.data.combinedData,
|
|
424
457
|
tx.data.constants,
|
|
425
458
|
);
|
|
426
459
|
return new RollupKernelData(
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { ContractDataSource, L1ToL2MessageSource, L2BlockSource } from '@aztec/circuit-types';
|
|
2
|
+
import { createDebugLogger } from '@aztec/foundation/log';
|
|
2
3
|
import { P2P } from '@aztec/p2p';
|
|
3
4
|
import { WorldStateSynchronizer } from '@aztec/world-state';
|
|
4
5
|
|
|
6
|
+
import * as fs from 'fs/promises';
|
|
7
|
+
|
|
5
8
|
import { SoloBlockBuilder } from '../block_builder/solo_block_builder.js';
|
|
6
9
|
import { SequencerClientConfig } from '../config.js';
|
|
7
10
|
import { getGlobalVariableBuilder } from '../global_variable_builder/index.js';
|
|
@@ -10,7 +13,32 @@ import { EmptyRollupProver } from '../prover/empty.js';
|
|
|
10
13
|
import { getL1Publisher } from '../publisher/index.js';
|
|
11
14
|
import { Sequencer, SequencerConfig } from '../sequencer/index.js';
|
|
12
15
|
import { PublicProcessorFactory } from '../sequencer/public_processor.js';
|
|
16
|
+
import { NativeACVMSimulator } from '../simulator/acvm_native.js';
|
|
17
|
+
import { WASMSimulator } from '../simulator/acvm_wasm.js';
|
|
13
18
|
import { RealRollupCircuitSimulator } from '../simulator/rollup.js';
|
|
19
|
+
import { SimulationProvider } from '../simulator/simulation_provider.js';
|
|
20
|
+
|
|
21
|
+
const logger = createDebugLogger('aztec:sequencer-client');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Factory function to create a simulation provider. Will attempt to use native binary simulation falling back to WASM if unavailable.
|
|
25
|
+
* @param config - The provided sequencer client configuration
|
|
26
|
+
* @returns The constructed simulation provider
|
|
27
|
+
*/
|
|
28
|
+
async function getSimulationProvider(config: SequencerClientConfig): Promise<SimulationProvider> {
|
|
29
|
+
if (config.acvmBinaryPath && config.acvmWorkingDirectory) {
|
|
30
|
+
try {
|
|
31
|
+
await fs.access(config.acvmBinaryPath, fs.constants.R_OK);
|
|
32
|
+
await fs.mkdir(config.acvmWorkingDirectory, { recursive: true });
|
|
33
|
+
logger(`Using native ACVM at ${config.acvmBinaryPath}`);
|
|
34
|
+
return new NativeACVMSimulator(config.acvmWorkingDirectory, config.acvmBinaryPath);
|
|
35
|
+
} catch {
|
|
36
|
+
logger(`Failed to access ACVM at ${config.acvmBinaryPath}, falling back to WASM`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
logger('Using WASM ACVM simulation');
|
|
40
|
+
return new WASMSimulator();
|
|
41
|
+
}
|
|
14
42
|
|
|
15
43
|
/**
|
|
16
44
|
* Encapsulates the full sequencer and publisher.
|
|
@@ -40,14 +68,21 @@ export class SequencerClient {
|
|
|
40
68
|
const globalsBuilder = getGlobalVariableBuilder(config);
|
|
41
69
|
const merkleTreeDb = worldStateSynchronizer.getLatest();
|
|
42
70
|
|
|
71
|
+
const simulationProvider = await getSimulationProvider(config);
|
|
72
|
+
|
|
43
73
|
const blockBuilder = new SoloBlockBuilder(
|
|
44
74
|
merkleTreeDb,
|
|
45
75
|
getVerificationKeys(),
|
|
46
|
-
new RealRollupCircuitSimulator(),
|
|
76
|
+
new RealRollupCircuitSimulator(simulationProvider),
|
|
47
77
|
new EmptyRollupProver(),
|
|
48
78
|
);
|
|
49
79
|
|
|
50
|
-
const publicProcessorFactory = new PublicProcessorFactory(
|
|
80
|
+
const publicProcessorFactory = new PublicProcessorFactory(
|
|
81
|
+
merkleTreeDb,
|
|
82
|
+
contractDataSource,
|
|
83
|
+
l1ToL2MessageSource,
|
|
84
|
+
simulationProvider,
|
|
85
|
+
);
|
|
51
86
|
|
|
52
87
|
const sequencer = new Sequencer(
|
|
53
88
|
publisher,
|
package/src/config.ts
CHANGED
|
@@ -48,6 +48,8 @@ export function getConfigEnvVars(): SequencerClientConfig {
|
|
|
48
48
|
OUTBOX_CONTRACT_ADDRESS,
|
|
49
49
|
COINBASE,
|
|
50
50
|
FEE_RECIPIENT,
|
|
51
|
+
ACVM_WORKING_DIRECTORY,
|
|
52
|
+
ACVM_BINARY_PATH,
|
|
51
53
|
} = process.env;
|
|
52
54
|
|
|
53
55
|
const publisherPrivateKey: Hex = SEQ_PUBLISHER_PRIVATE_KEY
|
|
@@ -82,5 +84,7 @@ export function getConfigEnvVars(): SequencerClientConfig {
|
|
|
82
84
|
// TODO: undefined should not be allowed for the following 2 values in PROD
|
|
83
85
|
coinbase: COINBASE ? EthAddress.fromString(COINBASE) : undefined,
|
|
84
86
|
feeRecipient: FEE_RECIPIENT ? AztecAddress.fromString(FEE_RECIPIENT) : undefined,
|
|
87
|
+
acvmWorkingDirectory: ACVM_WORKING_DIRECTORY ? ACVM_WORKING_DIRECTORY : undefined,
|
|
88
|
+
acvmBinaryPath: ACVM_BINARY_PATH ? ACVM_BINARY_PATH : undefined,
|
|
85
89
|
};
|
|
86
90
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
export * from './sequencer/index.js';
|
|
2
|
-
export * from './config.js';
|
|
3
|
-
export * from './publisher/index.js';
|
|
4
1
|
export * from './client/index.js';
|
|
2
|
+
export * from './config.js';
|
|
5
3
|
export * from './mocks/verification_keys.js';
|
|
4
|
+
export * from './publisher/index.js';
|
|
5
|
+
export * from './sequencer/index.js';
|
|
6
6
|
|
|
7
7
|
// Used by the node to simulate public parts of transactions. Should these be moved to a shared library?
|
|
8
|
-
export * from './sequencer/public_processor.js';
|
|
9
8
|
export * from './global_variable_builder/index.js';
|
|
9
|
+
export * from './sequencer/public_processor.js';
|
|
10
10
|
|
|
11
11
|
// Used by publisher test in e2e
|
|
12
|
-
export { RealRollupCircuitSimulator } from './simulator/rollup.js';
|
|
13
|
-
export { EmptyRollupProver } from './prover/empty.js';
|
|
14
12
|
export { SoloBlockBuilder } from './block_builder/solo_block_builder.js';
|
|
15
|
-
export {
|
|
13
|
+
export { EmptyRollupProver } from './prover/empty.js';
|
|
14
|
+
export { makeEmptyProcessedTx, makeProcessedTx, partitionReverts } from './sequencer/processed_tx.js';
|
|
15
|
+
export { WASMSimulator } from './simulator/acvm_wasm.js';
|
|
16
|
+
export { RealRollupCircuitSimulator } from './simulator/rollup.js';
|
|
17
|
+
export { SimulationProvider } from './simulator/simulation_provider.js';
|
|
@@ -172,15 +172,15 @@ export class L1Publisher implements L2BlockReceiver {
|
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
if (receipt.status) {
|
|
175
|
-
let
|
|
175
|
+
let txsEffectsHash;
|
|
176
176
|
if (receipt.logs.length === 1) {
|
|
177
|
-
//
|
|
178
|
-
|
|
177
|
+
// txsEffectsHash from IAvailabilityOracle.TxsPublished event
|
|
178
|
+
txsEffectsHash = receipt.logs[0].data;
|
|
179
179
|
} else {
|
|
180
180
|
this.log(`Expected 1 log, got ${receipt.logs.length}`);
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
this.log.info(`Block txs effects published,
|
|
183
|
+
this.log.info(`Block txs effects published, txsEffectsHash: ${txsEffectsHash}`);
|
|
184
184
|
break;
|
|
185
185
|
}
|
|
186
186
|
|
|
@@ -87,7 +87,7 @@ export class ViemTxSender implements L1PublisherTxSender {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
checkIfTxsAreAvailable(block: L2Block): Promise<boolean> {
|
|
90
|
-
const args = [`0x${block.body.
|
|
90
|
+
const args = [`0x${block.body.getTxsEffectsHash().toString('hex')}`] as const;
|
|
91
91
|
return this.availabilityOracleContract.read.isAvailable(args);
|
|
92
92
|
}
|
|
93
93
|
|