@aztec/sequencer-client 0.24.0 → 0.26.1

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.
Files changed (65) hide show
  1. package/dest/block_builder/solo_block_builder.d.ts +9 -9
  2. package/dest/block_builder/solo_block_builder.d.ts.map +1 -1
  3. package/dest/block_builder/solo_block_builder.js +26 -48
  4. package/dest/global_variable_builder/viem-reader.js +2 -2
  5. package/dest/publisher/l1-publisher.d.ts +0 -2
  6. package/dest/publisher/l1-publisher.d.ts.map +1 -1
  7. package/dest/publisher/l1-publisher.js +2 -3
  8. package/dest/publisher/viem-tx-sender.d.ts.map +1 -1
  9. package/dest/publisher/viem-tx-sender.js +6 -10
  10. package/dest/sequencer/abstract_phase_manager.d.ts +18 -25
  11. package/dest/sequencer/abstract_phase_manager.d.ts.map +1 -1
  12. package/dest/sequencer/abstract_phase_manager.js +141 -91
  13. package/dest/sequencer/{fee_distribution_phase_manager.d.ts → app_logic_phase_manager.d.ts} +9 -11
  14. package/dest/sequencer/app_logic_phase_manager.d.ts.map +1 -0
  15. package/dest/sequencer/app_logic_phase_manager.js +44 -0
  16. package/dest/sequencer/phase_manager_factory.d.ts +19 -0
  17. package/dest/sequencer/phase_manager_factory.d.ts.map +1 -0
  18. package/dest/sequencer/phase_manager_factory.js +51 -0
  19. package/dest/sequencer/processed_tx.d.ts +2 -2
  20. package/dest/sequencer/processed_tx.d.ts.map +1 -1
  21. package/dest/sequencer/processed_tx.js +7 -7
  22. package/dest/sequencer/public_processor.d.ts +1 -1
  23. package/dest/sequencer/public_processor.d.ts.map +1 -1
  24. package/dest/sequencer/public_processor.js +13 -11
  25. package/dest/sequencer/sequencer.d.ts +3 -3
  26. package/dest/sequencer/sequencer.d.ts.map +1 -1
  27. package/dest/sequencer/sequencer.js +23 -16
  28. package/dest/sequencer/{fee_preparation_phase_manager.d.ts → setup_phase_manager.d.ts} +9 -11
  29. package/dest/sequencer/setup_phase_manager.d.ts.map +1 -0
  30. package/dest/sequencer/setup_phase_manager.js +37 -0
  31. package/dest/sequencer/{application_logic_phase_manager.d.ts → teardown_phase_manager.d.ts} +9 -12
  32. package/dest/sequencer/teardown_phase_manager.d.ts.map +1 -0
  33. package/dest/sequencer/teardown_phase_manager.js +36 -0
  34. package/dest/simulator/index.d.ts +10 -4
  35. package/dest/simulator/index.d.ts.map +1 -1
  36. package/dest/simulator/public_executor.d.ts +8 -3
  37. package/dest/simulator/public_executor.d.ts.map +1 -1
  38. package/dest/simulator/public_executor.js +64 -11
  39. package/dest/simulator/public_kernel.d.ts +10 -4
  40. package/dest/simulator/public_kernel.d.ts.map +1 -1
  41. package/dest/simulator/public_kernel.js +33 -14
  42. package/package.json +14 -13
  43. package/src/block_builder/solo_block_builder.ts +61 -50
  44. package/src/global_variable_builder/viem-reader.ts +1 -1
  45. package/src/publisher/l1-publisher.ts +1 -4
  46. package/src/publisher/viem-tx-sender.ts +6 -12
  47. package/src/sequencer/abstract_phase_manager.ts +207 -145
  48. package/src/sequencer/app_logic_phase_manager.ts +75 -0
  49. package/src/sequencer/phase_manager_factory.ts +122 -0
  50. package/src/sequencer/processed_tx.ts +12 -13
  51. package/src/sequencer/public_processor.ts +29 -12
  52. package/src/sequencer/sequencer.ts +22 -15
  53. package/src/sequencer/{fee_distribution_phase_manager.ts → setup_phase_manager.ts} +23 -25
  54. package/src/sequencer/teardown_phase_manager.ts +67 -0
  55. package/src/simulator/index.ts +10 -6
  56. package/src/simulator/public_executor.ts +108 -10
  57. package/src/simulator/public_kernel.ts +39 -13
  58. package/dest/sequencer/application_logic_phase_manager.d.ts.map +0 -1
  59. package/dest/sequencer/application_logic_phase_manager.js +0 -64
  60. package/dest/sequencer/fee_distribution_phase_manager.d.ts.map +0 -1
  61. package/dest/sequencer/fee_distribution_phase_manager.js +0 -42
  62. package/dest/sequencer/fee_preparation_phase_manager.d.ts.map +0 -1
  63. package/dest/sequencer/fee_preparation_phase_manager.js +0 -42
  64. package/src/sequencer/application_logic_phase_manager.ts +0 -107
  65. package/src/sequencer/fee_preparation_phase_manager.ts +0 -79
@@ -0,0 +1,122 @@
1
+ import { Tx } from '@aztec/circuit-types';
2
+ import { GlobalVariables, Header, PublicKernelCircuitPublicInputs } from '@aztec/circuits.js';
3
+ import { PublicExecutor, PublicStateDB } from '@aztec/simulator';
4
+ import { MerkleTreeOperations } from '@aztec/world-state';
5
+
6
+ import { PublicProver } from '../prover/index.js';
7
+ import { PublicKernelCircuitSimulator } from '../simulator/index.js';
8
+ import { ContractsDataSourcePublicDB } from '../simulator/public_executor.js';
9
+ import { AbstractPhaseManager, PublicKernelPhase } from './abstract_phase_manager.js';
10
+ import { AppLogicPhaseManager } from './app_logic_phase_manager.js';
11
+ import { SetupPhaseManager } from './setup_phase_manager.js';
12
+ import { TeardownPhaseManager } from './teardown_phase_manager.js';
13
+
14
+ export class PhaseDidNotChangeError extends Error {
15
+ constructor(phase: PublicKernelPhase) {
16
+ super(`Tried to advance the phase from [${phase}] when the circuit still needs [${phase}]`);
17
+ }
18
+ }
19
+
20
+ export class CannotTransitionToSetupError extends Error {
21
+ constructor() {
22
+ super('Cannot transition to setup phase');
23
+ }
24
+ }
25
+
26
+ export class PhaseManagerFactory {
27
+ public static phaseFromTx(
28
+ tx: Tx,
29
+ db: MerkleTreeOperations,
30
+ publicExecutor: PublicExecutor,
31
+ publicKernel: PublicKernelCircuitSimulator,
32
+ publicProver: PublicProver,
33
+ globalVariables: GlobalVariables,
34
+ historicalHeader: Header,
35
+ publicContractsDB: ContractsDataSourcePublicDB,
36
+ publicStateDB: PublicStateDB,
37
+ ): AbstractPhaseManager | undefined {
38
+ if (tx.data.needsSetup) {
39
+ return new SetupPhaseManager(
40
+ db,
41
+ publicExecutor,
42
+ publicKernel,
43
+ publicProver,
44
+ globalVariables,
45
+ historicalHeader,
46
+ publicContractsDB,
47
+ publicStateDB,
48
+ );
49
+ } else if (tx.data.needsAppLogic) {
50
+ return new AppLogicPhaseManager(
51
+ db,
52
+ publicExecutor,
53
+ publicKernel,
54
+ publicProver,
55
+ globalVariables,
56
+ historicalHeader,
57
+ publicContractsDB,
58
+ publicStateDB,
59
+ );
60
+ } else if (tx.data.needsTeardown) {
61
+ return new TeardownPhaseManager(
62
+ db,
63
+ publicExecutor,
64
+ publicKernel,
65
+ publicProver,
66
+ globalVariables,
67
+ historicalHeader,
68
+ publicContractsDB,
69
+ publicStateDB,
70
+ );
71
+ } else {
72
+ return undefined;
73
+ }
74
+ }
75
+
76
+ public static phaseFromOutput(
77
+ output: PublicKernelCircuitPublicInputs,
78
+ currentPhaseManager: AbstractPhaseManager,
79
+ db: MerkleTreeOperations,
80
+ publicExecutor: PublicExecutor,
81
+ publicKernel: PublicKernelCircuitSimulator,
82
+ publicProver: PublicProver,
83
+ globalVariables: GlobalVariables,
84
+ historicalHeader: Header,
85
+ publicContractsDB: ContractsDataSourcePublicDB,
86
+ publicStateDB: PublicStateDB,
87
+ ): AbstractPhaseManager | undefined {
88
+ if (output.needsSetup) {
89
+ throw new CannotTransitionToSetupError();
90
+ } else if (output.needsAppLogic) {
91
+ if (currentPhaseManager.phase === PublicKernelPhase.APP_LOGIC) {
92
+ throw new PhaseDidNotChangeError(currentPhaseManager.phase);
93
+ }
94
+ return new AppLogicPhaseManager(
95
+ db,
96
+ publicExecutor,
97
+ publicKernel,
98
+ publicProver,
99
+ globalVariables,
100
+ historicalHeader,
101
+ publicContractsDB,
102
+ publicStateDB,
103
+ );
104
+ } else if (output.needsTeardown) {
105
+ if (currentPhaseManager.phase === PublicKernelPhase.TEARDOWN) {
106
+ throw new PhaseDidNotChangeError(currentPhaseManager.phase);
107
+ }
108
+ return new TeardownPhaseManager(
109
+ db,
110
+ publicExecutor,
111
+ publicKernel,
112
+ publicProver,
113
+ globalVariables,
114
+ historicalHeader,
115
+ publicContractsDB,
116
+ publicStateDB,
117
+ );
118
+ } else {
119
+ return undefined;
120
+ }
121
+ }
122
+ }
@@ -1,9 +1,10 @@
1
1
  import { ExtendedContractData, Tx, TxHash, TxL2Logs } from '@aztec/circuit-types';
2
2
  import {
3
- CombinedAccumulatedData,
4
3
  Fr,
5
4
  Header,
6
5
  Proof,
6
+ PublicAccumulatedNonRevertibleData,
7
+ PublicAccumulatedRevertibleData,
7
8
  PublicKernelCircuitPublicInputs,
8
9
  makeEmptyProof,
9
10
  } from '@aztec/circuits.js';
@@ -47,21 +48,19 @@ export type FailedTx = {
47
48
  * @param kernelOutput - Output of the kernel circuit simulation for this tx.
48
49
  * @param proof - Proof of the kernel circuit for this tx.
49
50
  */
50
- export async function makeProcessedTx(
51
- tx: Tx,
52
- kernelOutput?: PublicKernelCircuitPublicInputs,
53
- proof?: Proof,
54
- ): Promise<ProcessedTx> {
51
+ export function makeProcessedTx(tx: Tx, kernelOutput?: PublicKernelCircuitPublicInputs, proof?: Proof): ProcessedTx {
55
52
  return {
56
- hash: await tx.getTxHash(),
53
+ hash: tx.getTxHash(),
57
54
  data:
58
55
  kernelOutput ??
59
56
  new PublicKernelCircuitPublicInputs(
60
57
  tx.data.aggregationObject,
61
- tx.data.endNonRevertibleData,
62
- CombinedAccumulatedData.fromFinalAccumulatedData(tx.data.end),
58
+ PublicAccumulatedNonRevertibleData.fromPrivateAccumulatedNonRevertibleData(tx.data.endNonRevertibleData),
59
+ PublicAccumulatedRevertibleData.fromPrivateAccumulatedRevertibleData(tx.data.end),
63
60
  tx.data.constants,
64
- tx.data.isPrivate,
61
+ tx.data.needsSetup,
62
+ tx.data.needsAppLogic,
63
+ tx.data.needsTeardown,
65
64
  ),
66
65
  proof: proof ?? tx.proof,
67
66
  encryptedLogs: tx.encryptedLogs,
@@ -75,7 +74,7 @@ export async function makeProcessedTx(
75
74
  * Makes an empty tx from an empty kernel circuit public inputs.
76
75
  * @returns A processed empty tx.
77
76
  */
78
- export function makeEmptyProcessedTx(header: Header, chainId: Fr, version: Fr): Promise<ProcessedTx> {
77
+ export function makeEmptyProcessedTx(header: Header, chainId: Fr, version: Fr): ProcessedTx {
79
78
  const emptyKernelOutput = PublicKernelCircuitPublicInputs.empty();
80
79
  emptyKernelOutput.constants.historicalHeader = header;
81
80
  emptyKernelOutput.constants.txContext.chainId = chainId;
@@ -83,7 +82,7 @@ export function makeEmptyProcessedTx(header: Header, chainId: Fr, version: Fr):
83
82
  const emptyProof = makeEmptyProof();
84
83
 
85
84
  const hash = new TxHash(Fr.ZERO.toBuffer());
86
- return Promise.resolve({
85
+ return {
87
86
  hash,
88
87
  encryptedLogs: new TxL2Logs([]),
89
88
  unencryptedLogs: new TxL2Logs([]),
@@ -91,5 +90,5 @@ export function makeEmptyProcessedTx(header: Header, chainId: Fr, version: Fr):
91
90
  proof: emptyProof,
92
91
  newContracts: [ExtendedContractData.empty()],
93
92
  isEmpty: true,
94
- });
93
+ };
95
94
  }
@@ -1,6 +1,6 @@
1
1
  import { ContractDataSource, L1ToL2MessageSource, Tx } from '@aztec/circuit-types';
2
2
  import { TxSequencerProcessingStats } from '@aztec/circuit-types/stats';
3
- import { GlobalVariables, Header, Proof, PublicKernelCircuitPublicInputs } from '@aztec/circuits.js';
3
+ import { GlobalVariables, Header } from '@aztec/circuits.js';
4
4
  import { createDebugLogger } from '@aztec/foundation/log';
5
5
  import { Timer } from '@aztec/foundation/timer';
6
6
  import { PublicExecutor, PublicStateDB } from '@aztec/simulator';
@@ -12,7 +12,7 @@ import { PublicKernelCircuitSimulator } from '../simulator/index.js';
12
12
  import { ContractsDataSourcePublicDB, WorldStateDB, WorldStatePublicDB } from '../simulator/public_executor.js';
13
13
  import { RealPublicKernelCircuitSimulator } from '../simulator/public_kernel.js';
14
14
  import { AbstractPhaseManager } from './abstract_phase_manager.js';
15
- import { FeePreparationPhaseManager } from './fee_preparation_phase_manager.js';
15
+ import { PhaseManagerFactory } from './phase_manager_factory.js';
16
16
  import { FailedTx, ProcessedTx, makeEmptyProcessedTx, makeProcessedTx } from './processed_tx.js';
17
17
 
18
18
  /**
@@ -85,7 +85,8 @@ export class PublicProcessor {
85
85
  const failed: FailedTx[] = [];
86
86
 
87
87
  for (const tx of txs) {
88
- let phase: AbstractPhaseManager | undefined = new FeePreparationPhaseManager(
88
+ let phase: AbstractPhaseManager | undefined = PhaseManagerFactory.phaseFromTx(
89
+ tx,
89
90
  this.db,
90
91
  this.publicExecutor,
91
92
  this.publicKernel,
@@ -95,25 +96,41 @@ export class PublicProcessor {
95
96
  this.publicContractsDB,
96
97
  this.publicStateDB,
97
98
  );
98
- let publicKernelOutput: PublicKernelCircuitPublicInputs | undefined = undefined;
99
- let publicKernelProof: Proof | undefined = undefined;
99
+ this.log(`Beginning processing in phase ${phase?.phase} for tx ${tx.getTxHash()}`);
100
+ let { publicKernelPublicInput, publicKernelProof } = AbstractPhaseManager.getKernelOutputAndProof(
101
+ tx,
102
+ undefined,
103
+ undefined,
104
+ );
100
105
  const timer = new Timer();
101
106
  try {
102
107
  while (phase) {
103
- const output = await phase.handle(tx, publicKernelOutput, publicKernelProof);
104
- publicKernelOutput = output.publicKernelOutput;
108
+ const output = await phase.handle(tx, publicKernelPublicInput, publicKernelProof);
109
+ publicKernelPublicInput = output.publicKernelOutput;
105
110
  publicKernelProof = output.publicKernelProof;
106
- phase = phase.nextPhase();
111
+ phase = PhaseManagerFactory.phaseFromOutput(
112
+ publicKernelPublicInput,
113
+ phase,
114
+ this.db,
115
+ this.publicExecutor,
116
+ this.publicKernel,
117
+ this.publicProver,
118
+ this.globalVariables,
119
+ this.historicalHeader,
120
+ this.publicContractsDB,
121
+ this.publicStateDB,
122
+ );
107
123
  }
108
124
 
109
- const processedTransaction = await makeProcessedTx(tx, publicKernelOutput, publicKernelProof);
125
+ const processedTransaction = makeProcessedTx(tx, publicKernelPublicInput, publicKernelProof);
110
126
  result.push(processedTransaction);
111
127
 
112
- this.log(`Processed public part of ${tx.data.end.newNullifiers[0]}`, {
128
+ this.log(`Processed public part of ${tx.data.endNonRevertibleData.newNullifiers[0].value}`, {
113
129
  eventName: 'tx-sequencer-processing',
114
130
  duration: timer.ms(),
115
131
  publicDataUpdateRequests:
116
- processedTransaction.data.end.publicDataUpdateRequests.filter(x => !x.leafSlot.isZero()).length ?? 0,
132
+ processedTransaction.data.combinedData.publicDataUpdateRequests.filter(x => !x.leafSlot.isZero()).length ??
133
+ 0,
117
134
  ...tx.getStats(),
118
135
  } satisfies TxSequencerProcessingStats);
119
136
  } catch (err) {
@@ -129,7 +146,7 @@ export class PublicProcessor {
129
146
  * Makes an empty processed tx. Useful for padding a block to a power of two number of txs.
130
147
  * @returns A processed tx with empty data.
131
148
  */
132
- public makeEmptyProcessedTx(): Promise<ProcessedTx> {
149
+ public makeEmptyProcessedTx(): ProcessedTx {
133
150
  const { chainId, version } = this.globalVariables;
134
151
  return makeEmptyProcessedTx(this.historicalHeader, chainId, version);
135
152
  }
@@ -186,8 +186,8 @@ export class Sequencer {
186
186
  const [publicProcessorDuration, [processedTxs, failedTxs]] = await elapsed(() => processor.process(validTxs));
187
187
  if (failedTxs.length > 0) {
188
188
  const failedTxData = failedTxs.map(fail => fail.tx);
189
- this.log(`Dropping failed txs ${(await Tx.getHashes(failedTxData)).join(', ')}`);
190
- await this.p2pClient.deleteTxs(await Tx.getHashes(failedTxData));
189
+ this.log(`Dropping failed txs ${Tx.getHashes(failedTxData).join(', ')}`);
190
+ await this.p2pClient.deleteTxs(Tx.getHashes(failedTxData));
191
191
  }
192
192
 
193
193
  // Only accept processed transactions that are not double-spends,
@@ -205,7 +205,7 @@ export class Sequencer {
205
205
 
206
206
  // Get l1 to l2 messages from the contract
207
207
  this.log('Requesting L1 to L2 messages from contract');
208
- const l1ToL2Messages = await this.getPendingL1ToL2Messages();
208
+ const l1ToL2Messages = await this.getPendingL1ToL2EntryKeys();
209
209
  this.log('Successfully retrieved L1 to L2 messages from contract');
210
210
 
211
211
  // Build the new block by running the rollup circuits
@@ -213,7 +213,7 @@ export class Sequencer {
213
213
 
214
214
  await assertBlockHeight();
215
215
 
216
- const emptyTx = await processor.makeEmptyProcessedTx();
216
+ const emptyTx = processor.makeEmptyProcessedTx();
217
217
  const [rollupCircuitsDuration, block] = await elapsed(() =>
218
218
  this.buildBlock(processedValidTxs, l1ToL2Messages, emptyTx, newGlobalVariables),
219
219
  );
@@ -255,7 +255,7 @@ export class Sequencer {
255
255
  return;
256
256
  }
257
257
 
258
- const blockCalldataHash = block.getCalldataHash();
258
+ const blockCalldataHash = block.body.getCalldataHash();
259
259
  this.log.info(`Publishing ${newContracts.length} contracts in block ${block.number}`);
260
260
 
261
261
  const publishedContractData = await this.publisher.processNewContractData(
@@ -296,7 +296,7 @@ export class Sequencer {
296
296
  for (const tx of txs) {
297
297
  if (tx.data.constants.txContext.chainId.value !== globalVariables.chainId.value) {
298
298
  this.log(
299
- `Deleting tx for incorrect chain ${tx.data.constants.txContext.chainId.toString()}, tx hash ${await Tx.getHash(
299
+ `Deleting tx for incorrect chain ${tx.data.constants.txContext.chainId.toString()}, tx hash ${Tx.getHash(
300
300
  tx,
301
301
  )}`,
302
302
  );
@@ -304,17 +304,18 @@ export class Sequencer {
304
304
  continue;
305
305
  }
306
306
  if (await this.isTxDoubleSpend(tx)) {
307
- this.log(`Deleting double spend tx ${await Tx.getHash(tx)}`);
307
+ this.log(`Deleting double spend tx ${Tx.getHash(tx)}`);
308
308
  txsToDelete.push(tx);
309
309
  continue;
310
310
  } else if (this.isTxDoubleSpendSameBlock(tx, thisBlockNullifiers)) {
311
311
  // We don't drop these txs from the p2p pool immediately since they become valid
312
312
  // again if the current block fails to be published for some reason.
313
- this.log(`Skipping tx with double-spend for this same block ${await Tx.getHash(tx)}`);
313
+ this.log(`Skipping tx with double-spend for this same block ${Tx.getHash(tx)}`);
314
314
  continue;
315
315
  }
316
316
 
317
317
  tx.data.end.newNullifiers.forEach(n => thisBlockNullifiers.add(n.value.toBigInt()));
318
+ tx.data.endNonRevertibleData.newNullifiers.forEach(n => thisBlockNullifiers.add(n.value.toBigInt()));
318
319
  validTxs.push(tx);
319
320
  if (validTxs.length >= this.maxTxsPerBlock) {
320
321
  break;
@@ -323,7 +324,7 @@ export class Sequencer {
323
324
 
324
325
  // Make sure we remove these from the tx pool so we do not consider it again
325
326
  if (txsToDelete.length > 0) {
326
- await this.p2pClient.deleteTxs(await Tx.getHashes([...txsToDelete]));
327
+ await this.p2pClient.deleteTxs(Tx.getHashes([...txsToDelete]));
327
328
  }
328
329
 
329
330
  return validTxs;
@@ -370,12 +371,12 @@ export class Sequencer {
370
371
  }
371
372
 
372
373
  /**
373
- * Calls the archiver to pull upto `NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP` message keys
374
+ * Calls the archiver to pull upto `NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP` entry keys
374
375
  * (archiver returns the top messages sorted by fees)
375
- * @returns An array of L1 to L2 messages' messageKeys
376
+ * @returns An array of L1 to L2 messages' entryKeys
376
377
  */
377
- protected async getPendingL1ToL2Messages(): Promise<Fr[]> {
378
- return await this.l1ToL2MessageSource.getPendingL1ToL2Messages();
378
+ protected async getPendingL1ToL2EntryKeys(): Promise<Fr[]> {
379
+ return await this.l1ToL2MessageSource.getPendingL1ToL2EntryKeys();
379
380
  }
380
381
 
381
382
  /**
@@ -385,7 +386,10 @@ export class Sequencer {
385
386
  */
386
387
  protected isTxDoubleSpendSameBlock(tx: Tx | ProcessedTx, thisBlockNullifiers: Set<bigint>): boolean {
387
388
  // We only consider non-empty nullifiers
388
- const newNullifiers = tx.data.end.newNullifiers.filter(n => !n.isEmpty());
389
+ const newNullifiers = [
390
+ ...tx.data.endNonRevertibleData.newNullifiers.filter(n => !n.isEmpty()),
391
+ ...tx.data.end.newNullifiers.filter(n => !n.isEmpty()),
392
+ ];
389
393
 
390
394
  for (const nullifier of newNullifiers) {
391
395
  if (thisBlockNullifiers.has(nullifier.value.toBigInt())) {
@@ -403,7 +407,10 @@ export class Sequencer {
403
407
  */
404
408
  protected async isTxDoubleSpend(tx: Tx | ProcessedTx): Promise<boolean> {
405
409
  // We only consider non-empty nullifiers
406
- const newNullifiers = tx.data.end.newNullifiers.filter(n => !n.isEmpty());
410
+ const newNullifiers = [
411
+ ...tx.data.endNonRevertibleData.newNullifiers.filter(n => !n.isEmpty()),
412
+ ...tx.data.end.newNullifiers.filter(n => !n.isEmpty()),
413
+ ];
407
414
 
408
415
  // Ditch this tx if it has a repeated nullifiers
409
416
  const uniqNullifiers = new Set(newNullifiers.map(n => n.value.toBigInt()));
@@ -1,19 +1,18 @@
1
1
  import { Tx } from '@aztec/circuit-types';
2
- import { GlobalVariables, Header, Proof, PublicCallRequest, PublicKernelCircuitPublicInputs } from '@aztec/circuits.js';
3
- import { createDebugLogger } from '@aztec/foundation/log';
2
+ import { GlobalVariables, Header, Proof, PublicKernelCircuitPublicInputs } from '@aztec/circuits.js';
4
3
  import { PublicExecutor, PublicStateDB } from '@aztec/simulator';
5
4
  import { MerkleTreeOperations } from '@aztec/world-state';
6
5
 
7
6
  import { PublicProver } from '../prover/index.js';
8
7
  import { PublicKernelCircuitSimulator } from '../simulator/index.js';
9
8
  import { ContractsDataSourcePublicDB } from '../simulator/public_executor.js';
10
- import { AbstractPhaseManager } from './abstract_phase_manager.js';
9
+ import { AbstractPhaseManager, PublicKernelPhase } from './abstract_phase_manager.js';
11
10
  import { FailedTx } from './processed_tx.js';
12
11
 
13
12
  /**
14
13
  * The phase manager responsible for performing the fee preparation phase.
15
14
  */
16
- export class FeeDistributionPhaseManager extends AbstractPhaseManager {
15
+ export class SetupPhaseManager extends AbstractPhaseManager {
17
16
  constructor(
18
17
  protected db: MerkleTreeOperations,
19
18
  protected publicExecutor: PublicExecutor,
@@ -23,45 +22,44 @@ export class FeeDistributionPhaseManager extends AbstractPhaseManager {
23
22
  protected historicalHeader: Header,
24
23
  protected publicContractsDB: ContractsDataSourcePublicDB,
25
24
  protected publicStateDB: PublicStateDB,
26
-
27
- protected log = createDebugLogger('aztec:sequencer:fee-distribution'),
25
+ public phase: PublicKernelPhase = PublicKernelPhase.SETUP,
28
26
  ) {
29
- super(db, publicExecutor, publicKernel, publicProver, globalVariables, historicalHeader);
30
- }
31
-
32
- // this is a no-op for now
33
- extractEnqueuedPublicCalls(_tx: Tx): PublicCallRequest[] {
34
- return [];
27
+ super(db, publicExecutor, publicKernel, publicProver, globalVariables, historicalHeader, phase);
35
28
  }
36
29
 
37
30
  // this is a no-op for now
38
31
  async handle(
39
32
  tx: Tx,
40
- previousPublicKernelOutput?: PublicKernelCircuitPublicInputs,
41
- previousPublicKernelProof?: Proof,
33
+ previousPublicKernelOutput: PublicKernelCircuitPublicInputs,
34
+ previousPublicKernelProof: Proof,
42
35
  ): Promise<{
43
36
  /**
44
37
  * the output of the public kernel circuit for this phase
45
38
  */
46
- publicKernelOutput?: PublicKernelCircuitPublicInputs;
39
+ publicKernelOutput: PublicKernelCircuitPublicInputs;
47
40
  /**
48
41
  * the proof of the public kernel circuit for this phase
49
42
  */
50
- publicKernelProof?: Proof;
43
+ publicKernelProof: Proof;
51
44
  }> {
52
- this.log.debug(`Handle ${await tx.getTxHash()} with no-op`);
53
- return {
54
- publicKernelOutput: previousPublicKernelOutput,
55
- publicKernelProof: previousPublicKernelProof,
56
- };
57
- }
45
+ this.log(`Processing tx ${tx.getTxHash()}`);
46
+ this.log(`Executing enqueued public calls for tx ${tx.getTxHash()}`);
47
+ const [publicKernelOutput, publicKernelProof, newUnencryptedFunctionLogs] = await this.processEnqueuedPublicCalls(
48
+ tx,
49
+ previousPublicKernelOutput,
50
+ previousPublicKernelProof,
51
+ );
52
+ tx.unencryptedLogs.addFunctionLogs(newUnencryptedFunctionLogs);
53
+
54
+ // commit the state updates from this transaction
55
+ await this.publicStateDB.commit();
58
56
 
59
- nextPhase() {
60
- return undefined;
57
+ return { publicKernelOutput, publicKernelProof };
61
58
  }
62
59
 
63
60
  async rollback(tx: Tx, err: unknown): Promise<FailedTx> {
64
- this.log.warn(`Error processing tx ${await tx.getTxHash()}: ${err}`);
61
+ this.log.warn(`Error processing tx ${tx.getTxHash()}: ${err}`);
62
+ await this.publicStateDB.rollback();
65
63
  return {
66
64
  tx,
67
65
  error: err instanceof Error ? err : new Error('Unknown error'),
@@ -0,0 +1,67 @@
1
+ import { Tx } from '@aztec/circuit-types';
2
+ import { GlobalVariables, Header, Proof, PublicKernelCircuitPublicInputs } from '@aztec/circuits.js';
3
+ import { PublicExecutor, PublicStateDB } from '@aztec/simulator';
4
+ import { MerkleTreeOperations } from '@aztec/world-state';
5
+
6
+ import { PublicProver } from '../prover/index.js';
7
+ import { PublicKernelCircuitSimulator } from '../simulator/index.js';
8
+ import { ContractsDataSourcePublicDB } from '../simulator/public_executor.js';
9
+ import { AbstractPhaseManager, PublicKernelPhase } from './abstract_phase_manager.js';
10
+ import { FailedTx } from './processed_tx.js';
11
+
12
+ /**
13
+ * The phase manager responsible for performing the fee preparation phase.
14
+ */
15
+ export class TeardownPhaseManager extends AbstractPhaseManager {
16
+ constructor(
17
+ protected db: MerkleTreeOperations,
18
+ protected publicExecutor: PublicExecutor,
19
+ protected publicKernel: PublicKernelCircuitSimulator,
20
+ protected publicProver: PublicProver,
21
+ protected globalVariables: GlobalVariables,
22
+ protected historicalHeader: Header,
23
+ protected publicContractsDB: ContractsDataSourcePublicDB,
24
+ protected publicStateDB: PublicStateDB,
25
+ public phase: PublicKernelPhase = PublicKernelPhase.TEARDOWN,
26
+ ) {
27
+ super(db, publicExecutor, publicKernel, publicProver, globalVariables, historicalHeader, phase);
28
+ }
29
+
30
+ async handle(
31
+ tx: Tx,
32
+ previousPublicKernelOutput: PublicKernelCircuitPublicInputs,
33
+ previousPublicKernelProof: Proof,
34
+ ): Promise<{
35
+ /**
36
+ * the output of the public kernel circuit for this phase
37
+ */
38
+ publicKernelOutput: PublicKernelCircuitPublicInputs;
39
+ /**
40
+ * the proof of the public kernel circuit for this phase
41
+ */
42
+ publicKernelProof: Proof;
43
+ }> {
44
+ this.log(`Processing tx ${tx.getTxHash()}`);
45
+ this.log(`Executing enqueued public calls for tx ${tx.getTxHash()}`);
46
+ const [publicKernelOutput, publicKernelProof, newUnencryptedFunctionLogs] = await this.processEnqueuedPublicCalls(
47
+ tx,
48
+ previousPublicKernelOutput,
49
+ previousPublicKernelProof,
50
+ );
51
+ tx.unencryptedLogs.addFunctionLogs(newUnencryptedFunctionLogs);
52
+
53
+ // commit the state updates from this transaction
54
+ await this.publicStateDB.commit();
55
+
56
+ return { publicKernelOutput, publicKernelProof };
57
+ }
58
+
59
+ async rollback(tx: Tx, err: unknown): Promise<FailedTx> {
60
+ this.log.warn(`Error processing tx ${tx.getTxHash()}: ${err}`);
61
+ await this.publicStateDB.rollback();
62
+ return {
63
+ tx,
64
+ error: err instanceof Error ? err : new Error('Unknown error'),
65
+ };
66
+ }
67
+ }
@@ -37,17 +37,21 @@ export interface RollupSimulator {
37
37
  */
38
38
  export interface PublicKernelCircuitSimulator {
39
39
  /**
40
- * Simulates the public kernel circuit (with a previous private kernel circuit run) from its inputs.
40
+ * Simulates the public kernel setup circuit from its inputs.
41
41
  * @param inputs - Inputs to the circuit.
42
42
  * @returns The public inputs as outputs of the simulation.
43
43
  */
44
- publicKernelCircuitPrivateInput(inputs: PublicKernelCircuitPrivateInputs): Promise<PublicKernelCircuitPublicInputs>;
44
+ publicKernelCircuitSetup(inputs: PublicKernelCircuitPrivateInputs): Promise<PublicKernelCircuitPublicInputs>;
45
45
  /**
46
- * Simulates the public kernel circuit (with no previous public kernel circuit run) from its inputs.
46
+ * Simulates the public kernel app logic circuit from its inputs.
47
47
  * @param inputs - Inputs to the circuit.
48
48
  * @returns The public inputs as outputs of the simulation.
49
49
  */
50
- publicKernelCircuitNonFirstIteration(
51
- inputs: PublicKernelCircuitPrivateInputs,
52
- ): Promise<PublicKernelCircuitPublicInputs>;
50
+ publicKernelCircuitAppLogic(inputs: PublicKernelCircuitPrivateInputs): Promise<PublicKernelCircuitPublicInputs>;
51
+ /**
52
+ * Simulates the public kernel teardown circuit from its inputs.
53
+ * @param inputs - Inputs to the circuit.
54
+ * @returns The public inputs as outputs of the simulation.
55
+ */
56
+ publicKernelCircuitTeardown(inputs: PublicKernelCircuitPrivateInputs): Promise<PublicKernelCircuitPublicInputs>;
53
57
  }