@aztec/sequencer-client 0.28.1 → 0.29.0

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 (34) hide show
  1. package/dest/block_builder/index.d.ts +2 -4
  2. package/dest/block_builder/index.d.ts.map +1 -1
  3. package/dest/block_builder/solo_block_builder.d.ts +4 -7
  4. package/dest/block_builder/solo_block_builder.d.ts.map +1 -1
  5. package/dest/block_builder/solo_block_builder.js +18 -20
  6. package/dest/client/sequencer-client.d.ts +4 -3
  7. package/dest/client/sequencer-client.d.ts.map +1 -1
  8. package/dest/client/sequencer-client.js +1 -1
  9. package/dest/sequencer/abstract_phase_manager.d.ts.map +1 -1
  10. package/dest/sequencer/abstract_phase_manager.js +10 -11
  11. package/dest/sequencer/hints_builder.d.ts +1 -1
  12. package/dest/sequencer/hints_builder.d.ts.map +1 -1
  13. package/dest/sequencer/hints_builder.js +4 -4
  14. package/dest/sequencer/processed_tx.d.ts.map +1 -1
  15. package/dest/sequencer/processed_tx.js +3 -3
  16. package/dest/sequencer/public_processor.d.ts +2 -1
  17. package/dest/sequencer/public_processor.d.ts.map +1 -1
  18. package/dest/sequencer/public_processor.js +1 -1
  19. package/dest/sequencer/sequencer.d.ts +2 -11
  20. package/dest/sequencer/sequencer.d.ts.map +1 -1
  21. package/dest/sequencer/sequencer.js +8 -20
  22. package/dest/simulator/public_executor.d.ts +3 -5
  23. package/dest/simulator/public_executor.d.ts.map +1 -1
  24. package/dest/simulator/public_executor.js +18 -34
  25. package/package.json +13 -13
  26. package/src/block_builder/index.ts +2 -8
  27. package/src/block_builder/solo_block_builder.ts +18 -29
  28. package/src/client/sequencer-client.ts +2 -1
  29. package/src/sequencer/abstract_phase_manager.ts +9 -12
  30. package/src/sequencer/hints_builder.ts +2 -8
  31. package/src/sequencer/processed_tx.ts +2 -0
  32. package/src/sequencer/public_processor.ts +2 -1
  33. package/src/sequencer/sequencer.ts +8 -26
  34. package/src/simulator/public_executor.ts +15 -42
@@ -89,32 +89,28 @@ export class SoloBlockBuilder implements BlockBuilder {
89
89
  * Builds an L2 block with the given number containing the given txs, updating state trees.
90
90
  * @param globalVariables - Global variables to be used in the block.
91
91
  * @param txs - Processed transactions to include in the block.
92
- * @param newModelL1ToL2Messages - L1 to L2 messages emitted by the new inbox.
93
- * @param newL1ToL2Messages - L1 to L2 messages to be part of the block.
92
+ * @param l1ToL2Messages - L1 to L2 messages to be part of the block.
94
93
  * @param timestamp - Timestamp of the block.
95
94
  * @returns The new L2 block and a correctness proof as returned by the root rollup circuit.
96
95
  */
97
96
  public async buildL2Block(
98
97
  globalVariables: GlobalVariables,
99
98
  txs: ProcessedTx[],
100
- newModelL1ToL2Messages: Fr[], // TODO(#4492): Rename this when purging the old inbox
101
- newL1ToL2Messages: Fr[],
99
+ l1ToL2Messages: Fr[],
102
100
  ): Promise<[L2Block, Proof]> {
103
101
  // Check txs are good for processing by checking if all the tree snapshots in header are non-empty
104
102
  this.validateTxs(txs);
105
103
 
104
+ // We pad the messages as the circuits expect that.
105
+ const l1ToL2MessagesPadded = padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
106
+
106
107
  // We fill the tx batch with empty txs, we process only one tx at a time for now
107
- const [circuitsOutput, proof] = await this.runCircuits(
108
- globalVariables,
109
- txs,
110
- newModelL1ToL2Messages,
111
- newL1ToL2Messages,
112
- );
108
+ const [circuitsOutput, proof] = await this.runCircuits(globalVariables, txs, l1ToL2MessagesPadded);
113
109
 
114
110
  // Collect all new nullifiers, commitments, and contracts from all txs in this block
115
111
  const txEffects: TxEffect[] = txs.map(tx => toTxEffect(tx));
116
112
 
117
- const blockBody = new Body(padArrayEnd(newL1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP), txEffects);
113
+ const blockBody = new Body(l1ToL2MessagesPadded, txEffects);
118
114
 
119
115
  const l2Block = L2Block.fromFields({
120
116
  archive: circuitsOutput.archive,
@@ -160,8 +156,7 @@ export class SoloBlockBuilder implements BlockBuilder {
160
156
  protected async runCircuits(
161
157
  globalVariables: GlobalVariables,
162
158
  txs: ProcessedTx[],
163
- newModelL1ToL2Messages: Fr[], // TODO(#4492): Rename this when purging the old inbox
164
- newL1ToL2Messages: Fr[], // TODO(#4492): Nuke this when purging the old inbox
159
+ l1ToL2Messages: Tuple<Fr, typeof NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP>,
165
160
  ): Promise<[RootRollupPublicInputs, Proof]> {
166
161
  // Check that the length of the array of txs is a power of two
167
162
  // See https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2
@@ -170,16 +165,13 @@ export class SoloBlockBuilder implements BlockBuilder {
170
165
  }
171
166
 
172
167
  // BASE PARITY CIRCUIT (run in parallel)
168
+ // Note: In the future we will want to cache the results of empty base and root parity circuits so that we don't
169
+ // have to run them. (It will most likely be quite common that some base parity circuits will be "empty")
173
170
  let baseParityInputs: BaseParityInputs[] = [];
174
171
  let elapsedBaseParityOutputsPromise: Promise<[number, RootParityInput[]]>;
175
172
  {
176
- const newModelL1ToL2MessagesTuple = padArrayEnd(
177
- newModelL1ToL2Messages,
178
- Fr.ZERO,
179
- NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
180
- );
181
173
  baseParityInputs = Array.from({ length: NUM_BASE_PARITY_PER_ROOT_PARITY }, (_, i) =>
182
- BaseParityInputs.fromSlice(newModelL1ToL2MessagesTuple, i),
174
+ BaseParityInputs.fromSlice(l1ToL2Messages, i),
183
175
  );
184
176
 
185
177
  const baseParityOutputs: Promise<RootParityInput>[] = [];
@@ -189,9 +181,6 @@ export class SoloBlockBuilder implements BlockBuilder {
189
181
  elapsedBaseParityOutputsPromise = elapsed(() => Promise.all(baseParityOutputs));
190
182
  }
191
183
 
192
- // padArrayEnd throws if the array is already full. Otherwise it pads till we reach the required size
193
- const newL1ToL2MessagesTuple = padArrayEnd(newL1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
194
-
195
184
  // BASE ROLLUP CIRCUIT (run in parallel)
196
185
  let elapsedBaseRollupOutputsPromise: Promise<[number, [BaseOrMergeRollupPublicInputs, Proof][]]>;
197
186
  const baseRollupInputs: BaseRollupInputs[] = [];
@@ -302,7 +291,7 @@ export class SoloBlockBuilder implements BlockBuilder {
302
291
  outputSize: rootParityOutput.toBuffer().length,
303
292
  } satisfies CircuitSimulationStats);
304
293
 
305
- return this.rootRollupCircuit(mergeOutputLeft, mergeOutputRight, rootParityOutput, newL1ToL2MessagesTuple);
294
+ return this.rootRollupCircuit(mergeOutputLeft, mergeOutputRight, rootParityOutput, l1ToL2Messages);
306
295
  }
307
296
 
308
297
  protected async baseParityCircuit(inputs: BaseParityInputs): Promise<RootParityInput> {
@@ -365,15 +354,15 @@ export class SoloBlockBuilder implements BlockBuilder {
365
354
  left: [BaseOrMergeRollupPublicInputs, Proof],
366
355
  right: [BaseOrMergeRollupPublicInputs, Proof],
367
356
  l1ToL2Roots: RootParityInput,
368
- newL1ToL2Messages: Tuple<Fr, typeof NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP>,
357
+ l1ToL2Messages: Tuple<Fr, typeof NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP>,
369
358
  ): Promise<[RootRollupPublicInputs, Proof]> {
370
359
  this.debug(`Running root rollup circuit`);
371
- const rootInput = await this.getRootRollupInput(...left, ...right, l1ToL2Roots, newL1ToL2Messages);
360
+ const rootInput = await this.getRootRollupInput(...left, ...right, l1ToL2Roots, l1ToL2Messages);
372
361
 
373
- // Update the local trees to include the new l1 to l2 messages
362
+ // Update the local trees to include the l1 to l2 messages
374
363
  await this.db.appendLeaves(
375
364
  MerkleTreeId.L1_TO_L2_MESSAGE_TREE,
376
- newL1ToL2Messages.map(m => m.toBuffer()),
365
+ l1ToL2Messages.map(m => m.toBuffer()),
377
366
  );
378
367
 
379
368
  // Simulate and get proof for the root circuit
@@ -690,8 +679,8 @@ export class SoloBlockBuilder implements BlockBuilder {
690
679
  const newPublicDataReadsPreimages: Tuple<PublicDataTreeLeafPreimage, typeof MAX_PUBLIC_DATA_READS_PER_TX> =
691
680
  makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => PublicDataTreeLeafPreimage.empty());
692
681
 
693
- for (const i in tx.data.combinedData.publicDataReads) {
694
- const leafSlot = tx.data.combinedData.publicDataReads[i].leafSlot.value;
682
+ for (const i in tx.data.validationRequests.publicDataReads) {
683
+ const leafSlot = tx.data.validationRequests.publicDataReads[i].leafSlot.value;
695
684
  const lowLeafResult = await this.db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
696
685
  if (!lowLeafResult) {
697
686
  throw new Error(`Public data tree should have one initial leaf`);
@@ -1,6 +1,7 @@
1
- import { ContractDataSource, L1ToL2MessageSource, L2BlockSource } from '@aztec/circuit-types';
1
+ import { L1ToL2MessageSource, L2BlockSource } from '@aztec/circuit-types';
2
2
  import { createDebugLogger } from '@aztec/foundation/log';
3
3
  import { P2P } from '@aztec/p2p';
4
+ import { ContractDataSource } from '@aztec/types/contracts';
4
5
  import { WorldStateSynchronizer } from '@aztec/world-state';
5
6
 
6
7
  import * as fs from 'fs/promises';
@@ -11,14 +11,13 @@ import {
11
11
  MAX_NEW_L2_TO_L1_MSGS_PER_CALL,
12
12
  MAX_NEW_NOTE_HASHES_PER_CALL,
13
13
  MAX_NEW_NULLIFIERS_PER_CALL,
14
- MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX,
15
14
  MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
16
15
  MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL,
17
16
  MAX_NULLIFIER_READ_REQUESTS_PER_CALL,
18
17
  MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,
19
18
  MAX_PUBLIC_DATA_READS_PER_CALL,
19
+ MAX_PUBLIC_DATA_READS_PER_TX,
20
20
  MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,
21
- MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX,
22
21
  MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
23
22
  MembershipWitness,
24
23
  PrivateKernelTailCircuitPublicInputs,
@@ -291,15 +290,14 @@ export abstract class AbstractPhaseManager {
291
290
  const previousKernel = this.getPreviousKernelData(previousOutput, previousProof);
292
291
 
293
292
  if (this.phase === PublicKernelPhase.TAIL) {
294
- const { endNonRevertibleData, end } = previousOutput;
293
+ const { validationRequests, endNonRevertibleData, end } = previousOutput;
295
294
  const nullifierReadRequestHints = await this.hintsBuilder.getNullifierReadRequestHints(
296
- endNonRevertibleData.nullifierReadRequests,
297
- end.nullifierReadRequests,
295
+ validationRequests.nullifierReadRequests,
298
296
  endNonRevertibleData.newNullifiers,
299
297
  end.newNullifiers,
300
298
  );
301
299
  const nullifierNonExistentReadRequestHints = await this.hintsBuilder.getNullifierNonExistentReadRequestHints(
302
- endNonRevertibleData.nullifierNonExistentReadRequests,
300
+ validationRequests.nullifierNonExistentReadRequests,
303
301
  endNonRevertibleData.newNullifiers,
304
302
  end.newNullifiers,
305
303
  );
@@ -479,9 +477,8 @@ function patchPublicStorageActionOrdering(
479
477
  execResult: PublicExecutionResult,
480
478
  phase: PublicKernelPhase,
481
479
  ) {
482
- const { publicDataReads, publicDataUpdateRequests } = PhaseIsRevertible[phase]
483
- ? publicInputs.end
484
- : publicInputs.endNonRevertibleData;
480
+ const { publicDataUpdateRequests } = PhaseIsRevertible[phase] ? publicInputs.end : publicInputs.endNonRevertibleData;
481
+ const { publicDataReads } = publicInputs.validationRequests;
485
482
 
486
483
  // Convert ContractStorage* objects to PublicData* objects and sort them in execution order.
487
484
  // Note, this only pulls simulated reads/writes from the current phase,
@@ -518,14 +515,14 @@ function patchPublicStorageActionOrdering(
518
515
 
519
516
  const numReadsInKernel = arrayNonEmptyLength(publicDataReads, f => f.isEmpty());
520
517
  const numReadsBeforeThisEnqueuedCall = numReadsInKernel - simPublicDataReads.length;
521
- publicInputs[effectSet].publicDataReads = padArrayEnd(
518
+ publicInputs.validationRequests.publicDataReads = padArrayEnd(
522
519
  [
523
520
  // do not mess with items from previous top/enqueued calls in kernel output
524
- ...publicInputs[effectSet].publicDataReads.slice(0, numReadsBeforeThisEnqueuedCall),
521
+ ...publicInputs.validationRequests.publicDataReads.slice(0, numReadsBeforeThisEnqueuedCall),
525
522
  ...simPublicDataReads,
526
523
  ],
527
524
  PublicDataRead.empty(),
528
- PhaseIsRevertible[phase] ? MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX : MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX,
525
+ MAX_PUBLIC_DATA_READS_PER_TX,
529
526
  );
530
527
 
531
528
  const numUpdatesInKernel = arrayNonEmptyLength(publicDataUpdateRequests, f => f.isEmpty());
@@ -13,7 +13,6 @@ import {
13
13
  buildNullifierNonExistentReadRequestHints,
14
14
  buildNullifierReadRequestHints,
15
15
  concatAccumulatedData,
16
- mergeAccumulatedData,
17
16
  } from '@aztec/circuits.js';
18
17
  import { Tuple } from '@aztec/foundation/serialize';
19
18
  import { MerkleTreeOperations } from '@aztec/world-state';
@@ -22,18 +21,13 @@ export class HintsBuilder {
22
21
  constructor(private db: MerkleTreeOperations) {}
23
22
 
24
23
  getNullifierReadRequestHints(
25
- nullifierReadRequestsNonRevertible: Tuple<ReadRequestContext, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>,
26
- nullifierReadRequestsRevertible: Tuple<ReadRequestContext, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>,
24
+ nullifierReadRequests: Tuple<ReadRequestContext, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>,
27
25
  nullifiersNonRevertible: Tuple<SideEffectLinkedToNoteHash, typeof MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX>,
28
26
  nullifiersRevertible: Tuple<SideEffectLinkedToNoteHash, typeof MAX_REVERTIBLE_NULLIFIERS_PER_TX>,
29
27
  ) {
30
28
  return buildNullifierReadRequestHints(
31
29
  this,
32
- mergeAccumulatedData(
33
- MAX_NULLIFIER_READ_REQUESTS_PER_TX,
34
- nullifierReadRequestsNonRevertible,
35
- nullifierReadRequestsRevertible,
36
- ),
30
+ nullifierReadRequests,
37
31
  concatAccumulatedData(MAX_NEW_NULLIFIERS_PER_TX, nullifiersNonRevertible, nullifiersRevertible),
38
32
  );
39
33
  }
@@ -11,6 +11,7 @@ import {
11
11
  PublicKernelCircuitPublicInputs,
12
12
  SideEffect,
13
13
  SideEffectLinkedToNoteHash,
14
+ ValidationRequests,
14
15
  makeEmptyProof,
15
16
  } from '@aztec/circuits.js';
16
17
  import { Tuple, fromFieldsTuple } from '@aztec/foundation/serialize';
@@ -109,6 +110,7 @@ export function getPreviousOutputAndProof(
109
110
  } else {
110
111
  const publicKernelPublicInput = new PublicKernelCircuitPublicInputs(
111
112
  tx.data.aggregationObject,
113
+ ValidationRequests.empty(),
112
114
  PublicAccumulatedNonRevertibleData.fromPrivateAccumulatedNonRevertibleData(tx.data.endNonRevertibleData),
113
115
  PublicAccumulatedRevertibleData.fromPrivateAccumulatedRevertibleData(tx.data.end),
114
116
  tx.data.constants,
@@ -1,9 +1,10 @@
1
- import { ContractDataSource, L1ToL2MessageSource, SimulationError, Tx } from '@aztec/circuit-types';
1
+ import { L1ToL2MessageSource, SimulationError, Tx } from '@aztec/circuit-types';
2
2
  import { TxSequencerProcessingStats } from '@aztec/circuit-types/stats';
3
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';
7
+ import { ContractDataSource } from '@aztec/types/contracts';
7
8
  import { MerkleTreeOperations } from '@aztec/world-state';
8
9
 
9
10
  import { EmptyPublicProver } from '../prover/empty.js';
@@ -202,12 +202,10 @@ export class Sequencer {
202
202
 
203
203
  await assertBlockHeight();
204
204
 
205
- const newModelL1ToL2Messages = await this.l1ToL2MessageSource.getNewL1ToL2Messages(BigInt(newBlockNumber));
206
-
207
205
  // Get l1 to l2 messages from the contract
208
206
  this.log('Requesting L1 to L2 messages from contract');
209
- const l1ToL2Messages = await this.getPendingL1ToL2EntryKeys();
210
- this.log('Successfully retrieved L1 to L2 messages from contract');
207
+ const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(BigInt(newBlockNumber));
208
+ this.log(`Retrieved ${l1ToL2Messages.length} L1 to L2 messages for block ${newBlockNumber}`);
211
209
 
212
210
  // Build the new block by running the rollup circuits
213
211
  this.log(`Assembling block with txs ${processedValidTxs.map(tx => tx.hash).join(', ')}`);
@@ -216,7 +214,7 @@ export class Sequencer {
216
214
 
217
215
  const emptyTx = processor.makeEmptyProcessedTx();
218
216
  const [rollupCircuitsDuration, block] = await elapsed(() =>
219
- this.buildBlock(processedValidTxs, newModelL1ToL2Messages, l1ToL2Messages, emptyTx, newGlobalVariables),
217
+ this.buildBlock(processedValidTxs, l1ToL2Messages, emptyTx, newGlobalVariables),
220
218
  );
221
219
 
222
220
  this.log(`Assembled block ${block.number}`, {
@@ -314,16 +312,14 @@ export class Sequencer {
314
312
  /**
315
313
  * Pads the set of txs to a power of two and assembles a block by calling the block builder.
316
314
  * @param txs - Processed txs to include in the next block.
317
- * @param newModelL1ToL2Messages - L1 to L2 messages emitted by the new inbox.
318
- * @param newL1ToL2Messages - L1 to L2 messages to be part of the block.
315
+ * @param l1ToL2Messages - L1 to L2 messages to be part of the block.
319
316
  * @param emptyTx - Empty tx to repeat at the end of the block to pad to a power of two.
320
317
  * @param globalVariables - Global variables to use in the block.
321
318
  * @returns The new block.
322
319
  */
323
320
  protected async buildBlock(
324
321
  txs: ProcessedTx[],
325
- newModelL1ToL2Messages: Fr[], // TODO(#4492): Rename this when purging the old inbox
326
- newL1ToL2Messages: Fr[], // TODO(#4492): Nuke this when purging the old inbox
322
+ l1ToL2Messages: Fr[],
327
323
  emptyTx: ProcessedTx,
328
324
  globalVariables: GlobalVariables,
329
325
  ) {
@@ -332,24 +328,10 @@ export class Sequencer {
332
328
  const emptyTxCount = txsTargetSize - txs.length;
333
329
 
334
330
  const allTxs = [...txs, ...times(emptyTxCount, () => emptyTx)];
335
- this.log(`Building block ${globalVariables.blockNumber}`);
336
-
337
- const [block] = await this.blockBuilder.buildL2Block(
338
- globalVariables,
339
- allTxs,
340
- newModelL1ToL2Messages,
341
- newL1ToL2Messages,
342
- );
343
- return block;
344
- }
331
+ this.log(`Building block ${globalVariables.blockNumber.toBigInt()}`);
345
332
 
346
- /**
347
- * Calls the archiver to pull upto `NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP` entry keys
348
- * (archiver returns the top messages sorted by fees)
349
- * @returns An array of L1 to L2 messages' entryKeys
350
- */
351
- protected async getPendingL1ToL2EntryKeys(): Promise<Fr[]> {
352
- return await this.l1ToL2MessageSource.getPendingL1ToL2EntryKeys();
333
+ const [block] = await this.blockBuilder.buildL2Block(globalVariables, allTxs, l1ToL2Messages);
334
+ return block;
353
335
  }
354
336
 
355
337
  /**
@@ -1,6 +1,4 @@
1
1
  import {
2
- ContractDataSource,
3
- ExtendedContractData,
4
2
  L1ToL2MessageSource,
5
3
  MerkleTreeId,
6
4
  NullifierMembershipWitness,
@@ -22,9 +20,8 @@ import {
22
20
  import { computePublicDataTreeLeafSlot } from '@aztec/circuits.js/hash';
23
21
  import { createDebugLogger } from '@aztec/foundation/log';
24
22
  import { ClassRegistererAddress } from '@aztec/protocol-contracts/class-registerer';
25
- import { InstanceDeployerAddress } from '@aztec/protocol-contracts/instance-deployer';
26
23
  import { CommitmentsDB, MessageLoadOracleInputs, PublicContractsDB, PublicStateDB } from '@aztec/simulator';
27
- import { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/types/contracts';
24
+ import { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/types/contracts';
28
25
  import { MerkleTreeOperations } from '@aztec/world-state';
29
26
 
30
27
  /**
@@ -32,7 +29,6 @@ import { MerkleTreeOperations } from '@aztec/world-state';
32
29
  * Progressively records contracts in transaction as they are processed in a block.
33
30
  */
34
31
  export class ContractsDataSourcePublicDB implements PublicContractsDB {
35
- private cache = new Map<string, ExtendedContractData>();
36
32
  private instanceCache = new Map<string, ContractInstanceWithAddress>();
37
33
  private classCache = new Map<string, ContractClassPublic>();
38
34
 
@@ -51,7 +47,7 @@ export class ContractsDataSourcePublicDB implements PublicContractsDB {
51
47
  this.log(`Adding class ${e.contractClassId.toString()} to public execution contract cache`);
52
48
  this.classCache.set(e.contractClassId.toString(), e.toContractClassPublic());
53
49
  });
54
- ContractInstanceDeployedEvent.fromLogs(logs, InstanceDeployerAddress).forEach(e => {
50
+ ContractInstanceDeployedEvent.fromLogs(logs).forEach(e => {
55
51
  this.log(
56
52
  `Adding instance ${e.address.toString()} with class ${e.contractClassId.toString()} to public execution contract cache`,
57
53
  );
@@ -73,9 +69,7 @@ export class ContractsDataSourcePublicDB implements PublicContractsDB {
73
69
  ContractClassRegisteredEvent.fromLogs(logs, ClassRegistererAddress).forEach(e =>
74
70
  this.classCache.delete(e.contractClassId.toString()),
75
71
  );
76
- ContractInstanceDeployedEvent.fromLogs(logs, InstanceDeployerAddress).forEach(e =>
77
- this.instanceCache.delete(e.address.toString()),
78
- );
72
+ ContractInstanceDeployedEvent.fromLogs(logs).forEach(e => this.instanceCache.delete(e.address.toString()));
79
73
  return Promise.resolve();
80
74
  }
81
75
 
@@ -83,46 +77,25 @@ export class ContractsDataSourcePublicDB implements PublicContractsDB {
83
77
  return this.instanceCache.get(address.toString()) ?? (await this.db.getContract(address));
84
78
  }
85
79
 
86
- async getBytecode(address: AztecAddress, selector: FunctionSelector): Promise<Buffer | undefined> {
87
- const contract = await this.#getContract(address);
88
- return contract?.getPublicFunction(selector)?.bytecode;
80
+ public async getContractClass(contractClassId: Fr): Promise<ContractClassPublic | undefined> {
81
+ return this.classCache.get(contractClassId.toString()) ?? (await this.db.getContractClass(contractClassId));
89
82
  }
90
83
 
91
- async getIsInternal(address: AztecAddress, selector: FunctionSelector): Promise<boolean | undefined> {
92
- const contract = await this.#getContract(address);
93
- return contract?.getPublicFunction(selector)?.isInternal;
94
- }
95
-
96
- async getPortalContractAddress(address: AztecAddress): Promise<EthAddress | undefined> {
97
- const contract = await this.#getContract(address);
98
- return contract?.contractData.portalContractAddress;
99
- }
100
-
101
- async #getContract(address: AztecAddress): Promise<ExtendedContractData | undefined> {
102
- return (
103
- this.cache.get(address.toString()) ??
104
- (await this.#makeExtendedContractDataFor(address)) ??
105
- (await this.db.getExtendedContractData(address))
106
- );
107
- }
108
-
109
- async #makeExtendedContractDataFor(address: AztecAddress): Promise<ExtendedContractData | undefined> {
110
- const instance = this.instanceCache.get(address.toString());
84
+ async getBytecode(address: AztecAddress, selector: FunctionSelector): Promise<Buffer | undefined> {
85
+ const instance = await this.getContractInstance(address);
111
86
  if (!instance) {
112
- return undefined;
87
+ throw new Error(`Contract ${address.toString()} not found`);
113
88
  }
114
-
115
- const contractClass =
116
- this.classCache.get(instance.contractClassId.toString()) ??
117
- (await this.db.getContractClass(instance.contractClassId));
89
+ const contractClass = await this.getContractClass(instance.contractClassId);
118
90
  if (!contractClass) {
119
- this.log.warn(
120
- `Contract class ${instance.contractClassId.toString()} for address ${address.toString()} not found`,
121
- );
122
- return undefined;
91
+ throw new Error(`Contract class ${instance.contractClassId.toString()} for ${address.toString()} not found`);
123
92
  }
93
+ return contractClass.publicFunctions.find(f => f.selector.equals(selector))?.bytecode;
94
+ }
124
95
 
125
- return ExtendedContractData.fromClassAndInstance(contractClass, instance);
96
+ async getPortalContractAddress(address: AztecAddress): Promise<EthAddress | undefined> {
97
+ const contract = await this.getContractInstance(address);
98
+ return contract?.portalContractAddress;
126
99
  }
127
100
  }
128
101