@aztec/txe 0.0.1-commit.24de95ac → 0.0.1-commit.2e2504e2

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 (83) hide show
  1. package/dest/bin/index.d.ts +1 -1
  2. package/dest/constants.d.ts +3 -0
  3. package/dest/constants.d.ts.map +1 -0
  4. package/dest/constants.js +2 -0
  5. package/dest/index.d.ts +1 -1
  6. package/dest/index.d.ts.map +1 -1
  7. package/dest/index.js +3 -2
  8. package/dest/oracle/interfaces.d.ts +11 -8
  9. package/dest/oracle/interfaces.d.ts.map +1 -1
  10. package/dest/oracle/txe_oracle_public_context.d.ts +7 -7
  11. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  12. package/dest/oracle/txe_oracle_public_context.js +10 -12
  13. package/dest/oracle/txe_oracle_top_level_context.d.ts +22 -12
  14. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  15. package/dest/oracle/txe_oracle_top_level_context.js +128 -79
  16. package/dest/rpc_translator.d.ts +32 -17
  17. package/dest/rpc_translator.d.ts.map +1 -1
  18. package/dest/rpc_translator.js +134 -60
  19. package/dest/state_machine/archiver.d.ts +21 -51
  20. package/dest/state_machine/archiver.d.ts.map +1 -1
  21. package/dest/state_machine/archiver.js +63 -94
  22. package/dest/state_machine/dummy_p2p_client.d.ts +9 -6
  23. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  24. package/dest/state_machine/dummy_p2p_client.js +16 -8
  25. package/dest/state_machine/global_variable_builder.d.ts +6 -4
  26. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  27. package/dest/state_machine/global_variable_builder.js +13 -1
  28. package/dest/state_machine/index.d.ts +7 -7
  29. package/dest/state_machine/index.d.ts.map +1 -1
  30. package/dest/state_machine/index.js +39 -22
  31. package/dest/state_machine/mock_epoch_cache.d.ts +12 -10
  32. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  33. package/dest/state_machine/mock_epoch_cache.js +17 -13
  34. package/dest/state_machine/synchronizer.d.ts +3 -2
  35. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  36. package/dest/state_machine/synchronizer.js +5 -4
  37. package/dest/txe_session.d.ts +21 -13
  38. package/dest/txe_session.d.ts.map +1 -1
  39. package/dest/txe_session.js +101 -49
  40. package/dest/util/encoding.d.ts +615 -16
  41. package/dest/util/encoding.d.ts.map +1 -1
  42. package/dest/util/encoding.js +1 -1
  43. package/dest/util/expected_failure_error.d.ts +1 -1
  44. package/dest/util/expected_failure_error.d.ts.map +1 -1
  45. package/dest/util/txe_account_store.d.ts +10 -0
  46. package/dest/util/txe_account_store.d.ts.map +1 -0
  47. package/dest/util/{txe_account_data_provider.js → txe_account_store.js} +1 -1
  48. package/dest/util/txe_contract_store.d.ts +12 -0
  49. package/dest/util/txe_contract_store.d.ts.map +1 -0
  50. package/dest/util/{txe_contract_data_provider.js → txe_contract_store.js} +3 -3
  51. package/dest/util/txe_public_contract_data_source.d.ts +7 -6
  52. package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
  53. package/dest/util/txe_public_contract_data_source.js +11 -11
  54. package/dest/utils/block_creation.d.ts +21 -6
  55. package/dest/utils/block_creation.d.ts.map +1 -1
  56. package/dest/utils/block_creation.js +38 -4
  57. package/dest/utils/tx_effect_creation.d.ts +3 -3
  58. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  59. package/dest/utils/tx_effect_creation.js +4 -7
  60. package/package.json +18 -17
  61. package/src/constants.ts +3 -0
  62. package/src/index.ts +15 -12
  63. package/src/oracle/interfaces.ts +10 -7
  64. package/src/oracle/txe_oracle_public_context.ts +12 -19
  65. package/src/oracle/txe_oracle_top_level_context.ts +205 -107
  66. package/src/rpc_translator.ts +159 -63
  67. package/src/state_machine/archiver.ts +63 -117
  68. package/src/state_machine/dummy_p2p_client.ts +22 -10
  69. package/src/state_machine/global_variable_builder.ts +22 -4
  70. package/src/state_machine/index.ts +59 -21
  71. package/src/state_machine/mock_epoch_cache.ts +20 -20
  72. package/src/state_machine/synchronizer.ts +6 -5
  73. package/src/txe_session.ts +197 -85
  74. package/src/util/encoding.ts +1 -1
  75. package/src/util/{txe_account_data_provider.ts → txe_account_store.ts} +1 -1
  76. package/src/util/{txe_contract_data_provider.ts → txe_contract_store.ts} +3 -3
  77. package/src/util/txe_public_contract_data_source.ts +13 -12
  78. package/src/utils/block_creation.ts +49 -14
  79. package/src/utils/tx_effect_creation.ts +5 -12
  80. package/dest/util/txe_account_data_provider.d.ts +0 -10
  81. package/dest/util/txe_account_data_provider.d.ts.map +0 -1
  82. package/dest/util/txe_contract_data_provider.d.ts +0 -12
  83. package/dest/util/txe_contract_data_provider.d.ts.map +0 -1
@@ -1,10 +1,13 @@
1
1
  import { Fr, Point } from '@aztec/aztec.js/fields';
2
2
  import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX } from '@aztec/constants';
3
- import { packAsRetrievedNote } from '@aztec/pxe/simulator';
4
- import { FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
3
+ import { BlockNumber } from '@aztec/foundation/branded-types';
4
+ import { packAsHintedNote } from '@aztec/pxe/simulator';
5
+ import { EventSelector, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
5
6
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
6
- import { MerkleTreeId } from '@aztec/stdlib/trees';
7
+ import { BlockHash } from '@aztec/stdlib/block';
7
8
  import { addressFromSingle, arrayOfArraysToBoundedVecOfArrays, arrayToBoundedVec, bufferToU8Array, fromArray, fromSingle, fromUintArray, fromUintBoundedVec, toArray, toForeignCallResult, toSingle } from './util/encoding.js';
9
+ const MAX_EVENT_LEN = 12; // This is MAX_MESSAGE_CONTENT_LEN - PRIVATE_EVENT_RESERVED_FIELDS
10
+ const MAX_PRIVATE_EVENTS_PER_TXE_QUERY = 5;
8
11
  export class UnavailableOracleError extends Error {
9
12
  constructor(oracleName){
10
13
  super(`${oracleName} oracles not available with the current handler`);
@@ -64,7 +67,7 @@ export class RPCTranslator {
64
67
  }
65
68
  async txeSetPrivateTXEContext(foreignContractAddressIsSome, foreignContractAddressValue, foreignAnchorBlockNumberIsSome, foreignAnchorBlockNumberValue) {
66
69
  const contractAddress = fromSingle(foreignContractAddressIsSome).toBool() ? AztecAddress.fromField(fromSingle(foreignContractAddressValue)) : undefined;
67
- const anchorBlockNumber = fromSingle(foreignAnchorBlockNumberIsSome).toBool() ? fromSingle(foreignAnchorBlockNumberValue).toNumber() : undefined;
70
+ const anchorBlockNumber = fromSingle(foreignAnchorBlockNumberIsSome).toBool() ? BlockNumber(fromSingle(foreignAnchorBlockNumberValue).toNumber()) : undefined;
68
71
  const privateContextInputs = await this.stateHandler.enterPrivateState(contractAddress, anchorBlockNumber);
69
72
  return toForeignCallResult(privateContextInputs.toFields().map(toSingle));
70
73
  }
@@ -80,6 +83,12 @@ export class RPCTranslator {
80
83
  }
81
84
  // Other oracles - these get handled by the oracle handler
82
85
  // TXE-specific oracles
86
+ txeGetDefaultAddress() {
87
+ const defaultAddress = this.handlerAsTxe().txeGetDefaultAddress();
88
+ return toForeignCallResult([
89
+ toSingle(defaultAddress)
90
+ ]);
91
+ }
83
92
  async txeGetNextBlockNumber() {
84
93
  const nextBlockNumber = await this.handlerAsTxe().txeGetNextBlockNumber();
85
94
  return toForeignCallResult([
@@ -163,8 +172,29 @@ export class RPCTranslator {
163
172
  ...arrayToBoundedVec(toArray(nullifiers), MAX_NULLIFIERS_PER_TX)
164
173
  ]);
165
174
  }
166
- // Since the argument is a slice, noir automatically adds a length field to oracle call.
167
- privateStoreInExecutionCache(_foreignLength, foreignValues, foreignHash) {
175
+ async txeGetPrivateEvents(foreignSelector, foreignContractAddress, foreignScope) {
176
+ const selector = EventSelector.fromField(fromSingle(foreignSelector));
177
+ const contractAddress = addressFromSingle(foreignContractAddress);
178
+ const scope = addressFromSingle(foreignScope);
179
+ const events = await this.handlerAsTxe().txeGetPrivateEvents(selector, contractAddress, scope);
180
+ if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
181
+ throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
182
+ }
183
+ if (events.some((e)=>e.length > MAX_EVENT_LEN)) {
184
+ throw new Error(`Some private event has length larger than maxLen ${MAX_EVENT_LEN}`);
185
+ }
186
+ // This is a workaround as Noir does not currently let us return nested structs with arrays. We instead return a raw
187
+ // multidimensional array in get_private_events_oracle and create the BoundedVecs here.
188
+ const rawArrayStorage = events.map((e)=>e.concat(Array(MAX_EVENT_LEN - e.length).fill(new Fr(0)))).concat(Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(Array(MAX_EVENT_LEN).fill(new Fr(0)))).flat();
189
+ const eventLengths = events.map((e)=>new Fr(e.length)).concat(Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(new Fr(0)));
190
+ const queryLength = new Fr(events.length);
191
+ return toForeignCallResult([
192
+ toArray(rawArrayStorage),
193
+ toArray(eventLengths),
194
+ toSingle(queryLength)
195
+ ]);
196
+ }
197
+ privateStoreInExecutionCache(foreignValues, foreignHash) {
168
198
  const values = fromArray(foreignValues);
169
199
  const hash = fromSingle(foreignHash);
170
200
  this.handlerAsPrivate().privateStoreInExecutionCache(values, hash);
@@ -186,26 +216,28 @@ export class RPCTranslator {
186
216
  this.handlerAsMisc().utilityDebugLog(level, message, fields);
187
217
  return toForeignCallResult([]);
188
218
  }
189
- async utilityStorageRead(foreignContractAddress, foreignStartStorageSlot, foreignBlockNumber, foreignNumberOfElements) {
219
+ async utilityStorageRead(foreignBlockHash, foreignContractAddress, foreignStartStorageSlot, foreignNumberOfElements) {
220
+ const blockHash = new BlockHash(fromSingle(foreignBlockHash));
190
221
  const contractAddress = addressFromSingle(foreignContractAddress);
191
222
  const startStorageSlot = fromSingle(foreignStartStorageSlot);
192
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
193
223
  const numberOfElements = fromSingle(foreignNumberOfElements).toNumber();
194
- const values = await this.handlerAsUtility().utilityStorageRead(contractAddress, startStorageSlot, blockNumber, numberOfElements);
224
+ const values = await this.handlerAsUtility().utilityStorageRead(blockHash, contractAddress, startStorageSlot, numberOfElements);
195
225
  return toForeignCallResult([
196
226
  toArray(values)
197
227
  ]);
198
228
  }
199
- async utilityGetPublicDataWitness(foreignBlockNumber, foreignLeafSlot) {
200
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
229
+ async utilityGetPublicDataWitness(foreignBlockHash, foreignLeafSlot) {
230
+ const blockHash = new BlockHash(fromSingle(foreignBlockHash));
201
231
  const leafSlot = fromSingle(foreignLeafSlot);
202
- const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(blockNumber, leafSlot);
232
+ const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(blockHash, leafSlot);
203
233
  if (!witness) {
204
- throw new Error(`Public data witness not found for slot ${leafSlot} at block ${blockNumber}.`);
234
+ throw new Error(`Public data witness not found for slot ${leafSlot} at block ${blockHash.toString()}.`);
205
235
  }
206
236
  return toForeignCallResult(witness.toNoirRepresentation());
207
237
  }
208
- async utilityGetNotes(foreignStorageSlot, foreignNumSelects, foreignSelectByIndexes, foreignSelectByOffsets, foreignSelectByLengths, foreignSelectValues, foreignSelectComparators, foreignSortByIndexes, foreignSortByOffsets, foreignSortByLengths, foreignSortOrder, foreignLimit, foreignOffset, foreignStatus, foreignMaxNotes, foreignPackedRetrievedNoteLength) {
238
+ async utilityGetNotes(foreignOwnerIsSome, foreignOwnerValue, foreignStorageSlot, foreignNumSelects, foreignSelectByIndexes, foreignSelectByOffsets, foreignSelectByLengths, foreignSelectValues, foreignSelectComparators, foreignSortByIndexes, foreignSortByOffsets, foreignSortByLengths, foreignSortOrder, foreignLimit, foreignOffset, foreignStatus, foreignMaxNotes, foreignPackedHintedNoteLength) {
239
+ // Parse Option<AztecAddress>: ownerIsSome is 0 for None, 1 for Some
240
+ const owner = fromSingle(foreignOwnerIsSome).toBool() ? AztecAddress.fromField(fromSingle(foreignOwnerValue)) : undefined;
209
241
  const storageSlot = fromSingle(foreignStorageSlot);
210
242
  const numSelects = fromSingle(foreignNumSelects).toNumber();
211
243
  const selectByIndexes = fromArray(foreignSelectByIndexes).map((fr)=>fr.toNumber());
@@ -221,21 +253,31 @@ export class RPCTranslator {
221
253
  const offset = fromSingle(foreignOffset).toNumber();
222
254
  const status = fromSingle(foreignStatus).toNumber();
223
255
  const maxNotes = fromSingle(foreignMaxNotes).toNumber();
224
- const packedRetrievedNoteLength = fromSingle(foreignPackedRetrievedNoteLength).toNumber();
225
- const noteDatas = await this.handlerAsUtility().utilityGetNotes(storageSlot, numSelects, selectByIndexes, selectByOffsets, selectByLengths, selectValues, selectComparators, sortByIndexes, sortByOffsets, sortByLengths, sortOrder, limit, offset, status);
226
- const returnDataAsArrayOfArrays = noteDatas.map(packAsRetrievedNote);
256
+ const packedHintedNoteLength = fromSingle(foreignPackedHintedNoteLength).toNumber();
257
+ const noteDatas = await this.handlerAsUtility().utilityGetNotes(owner, storageSlot, numSelects, selectByIndexes, selectByOffsets, selectByLengths, selectValues, selectComparators, sortByIndexes, sortByOffsets, sortByLengths, sortOrder, limit, offset, status);
258
+ const returnDataAsArrayOfArrays = noteDatas.map((noteData)=>packAsHintedNote({
259
+ contractAddress: noteData.contractAddress,
260
+ owner: noteData.owner,
261
+ randomness: noteData.randomness,
262
+ storageSlot: noteData.storageSlot,
263
+ noteNonce: noteData.noteNonce,
264
+ isPending: noteData.isPending,
265
+ note: noteData.note
266
+ }));
227
267
  // Now we convert each sub-array to an array of ForeignCallSingles
228
268
  const returnDataAsArrayOfForeignCallSingleArrays = returnDataAsArrayOfArrays.map((subArray)=>subArray.map(toSingle));
229
269
  // At last we convert the array of arrays to a bounded vec of arrays
230
- return toForeignCallResult(arrayOfArraysToBoundedVecOfArrays(returnDataAsArrayOfForeignCallSingleArrays, maxNotes, packedRetrievedNoteLength));
270
+ return toForeignCallResult(arrayOfArraysToBoundedVecOfArrays(returnDataAsArrayOfForeignCallSingleArrays, maxNotes, packedHintedNoteLength));
231
271
  }
232
- privateNotifyCreatedNote(foreignStorageSlot, foreignNoteTypeId, foreignNote, foreignNoteHash, foreignCounter) {
272
+ privateNotifyCreatedNote(foreignOwner, foreignStorageSlot, foreignRandomness, foreignNoteTypeId, foreignNote, foreignNoteHash, foreignCounter) {
273
+ const owner = addressFromSingle(foreignOwner);
233
274
  const storageSlot = fromSingle(foreignStorageSlot);
275
+ const randomness = fromSingle(foreignRandomness);
234
276
  const noteTypeId = NoteSelector.fromField(fromSingle(foreignNoteTypeId));
235
277
  const note = fromArray(foreignNote);
236
278
  const noteHash = fromSingle(foreignNoteHash);
237
279
  const counter = fromSingle(foreignCounter).toNumber();
238
- this.handlerAsPrivate().privateNotifyCreatedNote(storageSlot, noteTypeId, note, noteHash, counter);
280
+ this.handlerAsPrivate().privateNotifyCreatedNote(owner, storageSlot, randomness, noteTypeId, note, noteHash, counter);
239
281
  return toForeignCallResult([]);
240
282
  }
241
283
  async privateNotifyNullifiedNote(foreignInnerNullifier, foreignNoteHash, foreignCounter) {
@@ -250,6 +292,14 @@ export class RPCTranslator {
250
292
  await this.handlerAsPrivate().privateNotifyCreatedNullifier(innerNullifier);
251
293
  return toForeignCallResult([]);
252
294
  }
295
+ async privateIsNullifierPending(foreignInnerNullifier, foreignContractAddress) {
296
+ const innerNullifier = fromSingle(foreignInnerNullifier);
297
+ const contractAddress = addressFromSingle(foreignContractAddress);
298
+ const isPending = await this.handlerAsPrivate().privateIsNullifierPending(innerNullifier, contractAddress);
299
+ return toForeignCallResult([
300
+ toSingle(new Fr(isPending))
301
+ ]);
302
+ }
253
303
  async utilityCheckNullifierExists(foreignInnerNullifier) {
254
304
  const innerNullifier = fromSingle(foreignInnerNullifier);
255
305
  const exists = await this.handlerAsUtility().utilityCheckNullifierExists(innerNullifier);
@@ -268,15 +318,27 @@ export class RPCTranslator {
268
318
  ...instance.publicKeys.toFields()
269
319
  ].map(toSingle));
270
320
  }
271
- async utilityGetPublicKeysAndPartialAddress(foreignAddress) {
321
+ async utilityTryGetPublicKeysAndPartialAddress(foreignAddress) {
272
322
  const address = addressFromSingle(foreignAddress);
273
- const { publicKeys, partialAddress } = await this.handlerAsUtility().utilityGetPublicKeysAndPartialAddress(address);
274
- return toForeignCallResult([
275
- toArray([
276
- ...publicKeys.toFields(),
277
- partialAddress
278
- ])
279
- ]);
323
+ const result = await this.handlerAsUtility().utilityTryGetPublicKeysAndPartialAddress(address);
324
+ // We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
325
+ // with two fields: `some` (a boolean) and `value` (a field array in this case).
326
+ if (result === undefined) {
327
+ // No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size.
328
+ return toForeignCallResult([
329
+ toSingle(new Fr(0)),
330
+ toArray(Array(13).fill(new Fr(0)))
331
+ ]);
332
+ } else {
333
+ // Data was found so we set `some` to 1 and return it along with `value`.
334
+ return toForeignCallResult([
335
+ toSingle(new Fr(1)),
336
+ toArray([
337
+ ...result.publicKeys.toFields(),
338
+ result.partialAddress
339
+ ])
340
+ ]);
341
+ }
280
342
  }
281
343
  async utilityGetKeyValidationRequest(foreignPkMHash) {
282
344
  const pkMHash = fromSingle(foreignPkMHash);
@@ -286,12 +348,12 @@ export class RPCTranslator {
286
348
  privateCallPrivateFunction(_foreignTargetContractAddress, _foreignFunctionSelector, _foreignArgsHash, _foreignSideEffectCounter, _foreignIsStaticCall) {
287
349
  throw new Error('Contract calls are forbidden inside a `TestEnvironment::private_context`, use `private_call` instead');
288
350
  }
289
- async utilityGetNullifierMembershipWitness(foreignBlockNumber, foreignNullifier) {
290
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
351
+ async utilityGetNullifierMembershipWitness(foreignBlockHash, foreignNullifier) {
352
+ const blockHash = new BlockHash(fromSingle(foreignBlockHash));
291
353
  const nullifier = fromSingle(foreignNullifier);
292
- const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockNumber, nullifier);
354
+ const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockHash, nullifier);
293
355
  if (!witness) {
294
- throw new Error(`Nullifier membership witness not found at block ${blockNumber}.`);
356
+ throw new Error(`Nullifier membership witness not found at block ${blockHash}.`);
295
357
  }
296
358
  return toForeignCallResult(witness.toNoirRepresentation());
297
359
  }
@@ -314,37 +376,49 @@ export class RPCTranslator {
314
376
  privateNotifySetMinRevertibleSideEffectCounter(_foreignMinRevertibleSideEffectCounter) {
315
377
  throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
316
378
  }
317
- async utilityGetUtilityContext() {
318
- const context = await this.handlerAsUtility().utilityGetUtilityContext();
379
+ async privateIsSideEffectCounterRevertible(foreignSideEffectCounter) {
380
+ const sideEffectCounter = fromSingle(foreignSideEffectCounter).toNumber();
381
+ const isRevertible = await this.handlerAsPrivate().privateIsSideEffectCounterRevertible(sideEffectCounter);
382
+ return toForeignCallResult([
383
+ toSingle(new Fr(isRevertible))
384
+ ]);
385
+ }
386
+ utilityGetUtilityContext() {
387
+ const context = this.handlerAsUtility().utilityGetUtilityContext();
319
388
  return toForeignCallResult(context.toNoirRepresentation());
320
389
  }
321
390
  async utilityGetBlockHeader(foreignBlockNumber) {
322
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
391
+ const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
323
392
  const header = await this.handlerAsUtility().utilityGetBlockHeader(blockNumber);
324
393
  if (!header) {
325
394
  throw new Error(`Block header not found for block ${blockNumber}.`);
326
395
  }
327
396
  return toForeignCallResult(header.toFields().map(toSingle));
328
397
  }
329
- async utilityGetMembershipWitness(foreignBlockNumber, foreignTreeId, foreignLeafValue) {
330
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
331
- const treeId = fromSingle(foreignTreeId).toNumber();
332
- const leafValue = fromSingle(foreignLeafValue);
333
- const witness = await this.handlerAsUtility().utilityGetMembershipWitness(blockNumber, treeId, leafValue);
398
+ async utilityGetNoteHashMembershipWitness(foreignAnchorBlockHash, foreignNoteHash) {
399
+ const blockHash = new BlockHash(fromSingle(foreignAnchorBlockHash));
400
+ const noteHash = fromSingle(foreignNoteHash);
401
+ const witness = await this.handlerAsUtility().utilityGetNoteHashMembershipWitness(blockHash, noteHash);
334
402
  if (!witness) {
335
- throw new Error(`Membership witness in tree ${MerkleTreeId[treeId]} not found for value ${leafValue} at block ${blockNumber}.`);
403
+ throw new Error(`Note hash ${noteHash} not found in the note hash tree at block ${blockHash.toString()}.`);
336
404
  }
337
- return toForeignCallResult([
338
- toSingle(witness[0]),
339
- toArray(witness.slice(1))
340
- ]);
405
+ return toForeignCallResult(witness.toNoirRepresentation());
406
+ }
407
+ async utilityGetBlockHashMembershipWitness(foreignAnchorBlockHash, foreignBlockHash) {
408
+ const anchorBlockHash = new BlockHash(fromSingle(foreignAnchorBlockHash));
409
+ const blockHash = new BlockHash(fromSingle(foreignBlockHash));
410
+ const witness = await this.handlerAsUtility().utilityGetBlockHashMembershipWitness(anchorBlockHash, blockHash);
411
+ if (!witness) {
412
+ throw new Error(`Block hash ${blockHash.toString()} not found in the archive tree at anchor block ${anchorBlockHash.toString()}.`);
413
+ }
414
+ return toForeignCallResult(witness.toNoirRepresentation());
341
415
  }
342
- async utilityGetLowNullifierMembershipWitness(foreignBlockNumber, foreignNullifier) {
343
- const blockNumber = fromSingle(foreignBlockNumber).toNumber();
416
+ async utilityGetLowNullifierMembershipWitness(foreignBlockHash, foreignNullifier) {
417
+ const blockHash = new BlockHash(fromSingle(foreignBlockHash));
344
418
  const nullifier = fromSingle(foreignNullifier);
345
- const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockNumber, nullifier);
419
+ const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockHash, nullifier);
346
420
  if (!witness) {
347
- throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${blockNumber}.`);
421
+ throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${blockHash}.`);
348
422
  }
349
423
  return toForeignCallResult(witness.toNoirRepresentation());
350
424
  }
@@ -353,11 +427,11 @@ export class RPCTranslator {
353
427
  await this.handlerAsUtility().utilityFetchTaggedLogs(pendingTaggedLogArrayBaseSlot);
354
428
  return toForeignCallResult([]);
355
429
  }
356
- async utilityValidateEnqueuedNotesAndEvents(foreignContractAddress, foreignNoteValidationRequestsArrayBaseSlot, foreignEventValidationRequestsArrayBaseSlot) {
430
+ async utilityValidateAndStoreEnqueuedNotesAndEvents(foreignContractAddress, foreignNoteValidationRequestsArrayBaseSlot, foreignEventValidationRequestsArrayBaseSlot) {
357
431
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
358
432
  const noteValidationRequestsArrayBaseSlot = fromSingle(foreignNoteValidationRequestsArrayBaseSlot);
359
433
  const eventValidationRequestsArrayBaseSlot = fromSingle(foreignEventValidationRequestsArrayBaseSlot);
360
- await this.handlerAsUtility().utilityValidateEnqueuedNotesAndEvents(contractAddress, noteValidationRequestsArrayBaseSlot, eventValidationRequestsArrayBaseSlot);
434
+ await this.handlerAsUtility().utilityValidateAndStoreEnqueuedNotesAndEvents(contractAddress, noteValidationRequestsArrayBaseSlot, eventValidationRequestsArrayBaseSlot);
361
435
  return toForeignCallResult([]);
362
436
  }
363
437
  async utilityBulkRetrieveLogs(foreignContractAddress, foreignLogRetrievalRequestsArrayBaseSlot, foreignLogRetrievalResponsesArrayBaseSlot) {
@@ -438,9 +512,10 @@ export class RPCTranslator {
438
512
  // TODO(#8811): Implement
439
513
  return toForeignCallResult([]);
440
514
  }
441
- async avmOpcodeStorageRead(foreignSlot) {
515
+ async avmOpcodeStorageRead(foreignSlot, foreignContractAddress) {
442
516
  const slot = fromSingle(foreignSlot);
443
- const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot)).value;
517
+ const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
518
+ const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot, contractAddress)).value;
444
519
  return toForeignCallResult([
445
520
  toSingle(new Fr(value))
446
521
  ]);
@@ -494,10 +569,9 @@ export class RPCTranslator {
494
569
  await this.handlerAsAvm().avmOpcodeEmitNoteHash(noteHash);
495
570
  return toForeignCallResult([]);
496
571
  }
497
- async avmOpcodeNullifierExists(foreignInnerNullifier, foreignTargetAddress) {
498
- const innerNullifier = fromSingle(foreignInnerNullifier);
499
- const targetAddress = AztecAddress.fromField(fromSingle(foreignTargetAddress));
500
- const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(innerNullifier, targetAddress);
572
+ async avmOpcodeNullifierExists(foreignSiloedNullifier) {
573
+ const siloedNullifier = fromSingle(foreignSiloedNullifier);
574
+ const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(siloedNullifier);
501
575
  return toForeignCallResult([
502
576
  toSingle(new Fr(exists))
503
577
  ]);
@@ -553,7 +627,7 @@ export class RPCTranslator {
553
627
  avmOpcodeSuccessCopy() {
554
628
  throw new Error('Contract calls are forbidden inside a `TestEnvironment::public_context`, use `public_call` instead');
555
629
  }
556
- async txePrivateCallNewFlow(foreignFrom, foreignTargetContractAddress, foreignFunctionSelector, _foreignArgsLength, foreignArgs, foreignArgsHash, foreignIsStaticCall) {
630
+ async txePrivateCallNewFlow(foreignFrom, foreignTargetContractAddress, foreignFunctionSelector, foreignArgs, foreignArgsHash, foreignIsStaticCall) {
557
631
  const from = addressFromSingle(foreignFrom);
558
632
  const targetContractAddress = addressFromSingle(foreignTargetContractAddress);
559
633
  const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
@@ -565,7 +639,7 @@ export class RPCTranslator {
565
639
  toArray(returnValues)
566
640
  ]);
567
641
  }
568
- async txeSimulateUtilityFunction(foreignTargetContractAddress, foreignFunctionSelector, _foreignArgsLength, foreignArgs) {
642
+ async txeSimulateUtilityFunction(foreignTargetContractAddress, foreignFunctionSelector, foreignArgs) {
569
643
  const targetContractAddress = addressFromSingle(foreignTargetContractAddress);
570
644
  const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
571
645
  const args = fromArray(foreignArgs);
@@ -574,7 +648,7 @@ export class RPCTranslator {
574
648
  toArray(returnValues)
575
649
  ]);
576
650
  }
577
- async txePublicCallNewFlow(foreignFrom, foreignAddress, _foreignLength, foreignCalldata, foreignIsStaticCall) {
651
+ async txePublicCallNewFlow(foreignFrom, foreignAddress, foreignCalldata, foreignIsStaticCall) {
578
652
  const from = addressFromSingle(foreignFrom);
579
653
  const address = addressFromSingle(foreignAddress);
580
654
  const calldata = fromArray(foreignCalldata);
@@ -1,61 +1,31 @@
1
- import { ArchiverStoreHelper, type PublishedL2Block } from '@aztec/archiver';
1
+ import { ArchiverDataSourceBase } from '@aztec/archiver';
2
+ import { type EpochNumber, type SlotNumber } from '@aztec/foundation/branded-types';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
2
4
  import type { EthAddress } from '@aztec/foundation/eth-address';
3
- import { Fr } from '@aztec/foundation/fields';
4
5
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
5
- import type { AztecAddress } from '@aztec/stdlib/aztec-address';
6
- import type { L2Block, L2BlockSource, L2Tips, ValidateBlockResult } from '@aztec/stdlib/block';
7
- import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
6
+ import type { L2Tips, ValidateCheckpointResult } from '@aztec/stdlib/block';
7
+ import type { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
8
8
  import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
9
- import type { BlockHeader } from '@aztec/stdlib/tx';
10
- import type { UInt64 } from '@aztec/stdlib/types';
11
- export declare class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
9
+ /**
10
+ * TXE Archiver implementation.
11
+ * Provides most of the endpoints needed by the node for reading from and writing to state,
12
+ * without needing any of the extra overhead that the Archiver itself requires (i.e. an L1 client).
13
+ */
14
+ export declare class TXEArchiver extends ArchiverDataSourceBase {
15
+ private readonly updater;
12
16
  constructor(db: AztecAsyncKVStore);
13
- addBlocks(blocks: PublishedL2Block[]): Promise<boolean>;
14
- /**
15
- * Gets the number of the latest L2 block processed by the block source implementation.
16
- * @returns The number of the latest L2 block processed by the block source implementation.
17
- */
18
- getBlockNumber(): Promise<number>;
19
- /**
20
- * Gets the number of the latest L2 block proven seen by the block source implementation.
21
- * @returns The number of the latest L2 block proven seen by the block source implementation.
22
- */
23
- getProvenBlockNumber(): Promise<number>;
24
- /**
25
- * Gets a published l2 block. If a negative number is passed, the block returned is the most recent.
26
- * @param number - The block number to return (inclusive).
27
- * @returns The requested L2 block.
28
- */
29
- getPublishedBlock(number: number): Promise<PublishedL2Block | undefined>;
30
- /**
31
- * Gets an l2 block. If a negative number is passed, the block returned is the most recent.
32
- * @param number - The block number to return (inclusive).
33
- * @returns The requested L2 block.
34
- */
35
- getBlock(number: number | 'latest'): Promise<L2Block | undefined>;
36
- /**
37
- * Gets an l2 block header.
38
- * @param number - The block number to return or 'latest' for the most recent one.
39
- * @returns The requested L2 block header.
40
- */
41
- getBlockHeader(number: number | 'latest'): Promise<BlockHeader | undefined>;
42
- getBlocks(from: number, limit: number, _proven?: boolean): Promise<L2Block[]>;
43
- getL2SlotNumber(): Promise<bigint>;
44
- getL2EpochNumber(): Promise<bigint>;
45
- getBlocksForEpoch(_epochNumber: bigint): Promise<L2Block[]>;
46
- getBlockHeadersForEpoch(_epochNumber: bigint): Promise<BlockHeader[]>;
47
- isEpochComplete(_epochNumber: bigint): Promise<boolean>;
48
- getL2Tips(): Promise<L2Tips>;
17
+ addCheckpoints(checkpoints: PublishedCheckpoint[], result?: ValidateCheckpointResult): Promise<void>;
18
+ getRollupAddress(): Promise<EthAddress>;
19
+ getRegistryAddress(): Promise<EthAddress>;
49
20
  getL1Constants(): Promise<L1RollupConstants>;
50
21
  getGenesisValues(): Promise<{
51
22
  genesisArchiveRoot: Fr;
52
23
  }>;
24
+ getL1Timestamp(): Promise<bigint | undefined>;
25
+ getL2Tips(): Promise<L2Tips>;
26
+ getL2SlotNumber(): Promise<SlotNumber | undefined>;
27
+ getL2EpochNumber(): Promise<EpochNumber | undefined>;
28
+ isEpochComplete(_epochNumber: EpochNumber): Promise<boolean>;
53
29
  syncImmediate(): Promise<void>;
54
- getContract(_address: AztecAddress, _timestamp?: UInt64): Promise<ContractInstanceWithAddress | undefined>;
55
- getRollupAddress(): Promise<EthAddress>;
56
- getRegistryAddress(): Promise<EthAddress>;
57
- getL1Timestamp(): Promise<bigint>;
58
- isPendingChainInvalid(): Promise<boolean>;
59
- getPendingChainValidationStatus(): Promise<ValidateBlockResult>;
60
30
  }
61
- //# sourceMappingURL=archiver.d.ts.map
31
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJjaGl2ZXIuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdGF0ZV9tYWNoaW5lL2FyY2hpdmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxzQkFBc0IsRUFBaUQsTUFBTSxpQkFBaUIsQ0FBQztBQUV4RyxPQUFPLEVBQW9CLEtBQUssV0FBVyxFQUFFLEtBQUssVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDdEcsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3BELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2hFLE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDekQsT0FBTyxLQUFLLEVBQW9DLE1BQU0sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzlHLE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDcEUsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUVyRTs7OztHQUlHO0FBQ0gscUJBQWEsV0FBWSxTQUFRLHNCQUFzQjtJQUNyRCxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBNEM7SUFFcEUsWUFBWSxFQUFFLEVBQUUsaUJBQWlCLEVBR2hDO0lBRVksY0FBYyxDQUFDLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxFQUFFLE1BQU0sQ0FBQyxFQUFFLHdCQUF3QixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FFaEg7SUFFTSxnQkFBZ0IsSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDLENBRTdDO0lBRU0sa0JBQWtCLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUUvQztJQUVNLGNBQWMsSUFBSSxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FFbEQ7SUFFTSxnQkFBZ0IsSUFBSSxPQUFPLENBQUM7UUFBRSxrQkFBa0IsRUFBRSxFQUFFLENBQUE7S0FBRSxDQUFDLENBRTdEO0lBRU0sY0FBYyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLENBRW5EO0lBRVksU0FBUyxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FnQ3hDO0lBRU0sZUFBZSxJQUFJLE9BQU8sQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLENBRXhEO0lBRU0sZ0JBQWdCLElBQUksT0FBTyxDQUFDLFdBQVcsR0FBRyxTQUFTLENBQUMsQ0FFMUQ7SUFFTSxlQUFlLENBQUMsWUFBWSxFQUFFLFdBQVcsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBRWxFO0lBRU0sYUFBYSxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FFcEM7Q0FDRiJ9
@@ -1 +1 @@
1
- {"version":3,"file":"archiver.d.ts","sourceRoot":"","sources":["../../src/state_machine/archiver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAuB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAElG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/F,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAKlD,qBAAa,WAAY,SAAQ,mBAAoB,YAAW,aAAa;gBAC/D,EAAE,EAAE,iBAAiB;IAIX,SAAS,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAS7E;;;OAGG;IACI,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAIxC;;;OAGG;IACI,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IAI9C;;;;OAIG;IACmB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAY9F;;;;OAIG;IACI,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAIxE;;;;OAIG;IACU,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAWjF,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAI7E,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC;IAIlC,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;IAInC,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAI3D,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAIrE,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIvD,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAI5B,cAAc,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAI5C,gBAAgB,IAAI,OAAO,CAAC;QAAE,kBAAkB,EAAE,EAAE,CAAA;KAAE,CAAC;IAIvD,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B,WAAW,CAAC,QAAQ,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,2BAA2B,GAAG,SAAS,CAAC;IAI1G,gBAAgB,IAAI,OAAO,CAAC,UAAU,CAAC;IAIvC,kBAAkB,IAAI,OAAO,CAAC,UAAU,CAAC;IAIzC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAIjC,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC;IAIhC,+BAA+B,IAAI,OAAO,CAAC,mBAAmB,CAAC;CAGhF"}
1
+ {"version":3,"file":"archiver.d.ts","sourceRoot":"","sources":["../../src/state_machine/archiver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAiD,MAAM,iBAAiB,CAAC;AAExG,OAAO,EAAoB,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACtG,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAoC,MAAM,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC9G,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAErE;;;;GAIG;AACH,qBAAa,WAAY,SAAQ,sBAAsB;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4C;IAEpE,YAAY,EAAE,EAAE,iBAAiB,EAGhC;IAEY,cAAc,CAAC,WAAW,EAAE,mBAAmB,EAAE,EAAE,MAAM,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhH;IAEM,gBAAgB,IAAI,OAAO,CAAC,UAAU,CAAC,CAE7C;IAEM,kBAAkB,IAAI,OAAO,CAAC,UAAU,CAAC,CAE/C;IAEM,cAAc,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAElD;IAEM,gBAAgB,IAAI,OAAO,CAAC;QAAE,kBAAkB,EAAE,EAAE,CAAA;KAAE,CAAC,CAE7D;IAEM,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAEnD;IAEY,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAgCxC;IAEM,eAAe,IAAI,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAExD;IAEM,gBAAgB,IAAI,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAE1D;IAEM,eAAe,CAAC,YAAY,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAElE;IAEM,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAEpC;CACF"}
@@ -1,70 +1,76 @@
1
- import { ArchiverStoreHelper, KVArchiverDataStore } from '@aztec/archiver';
1
+ import { ArchiverDataSourceBase, ArchiverDataStoreUpdater, KVArchiverDataStore } from '@aztec/archiver';
2
2
  import { GENESIS_ARCHIVE_ROOT } from '@aztec/constants';
3
- import { Fr } from '@aztec/foundation/fields';
4
- // We are extending the ArchiverDataStoreHelper here because it provides most of the endpoints needed by the
5
- // node for reading from and writing to state, without needing any of the extra overhead that the Archiver itself
6
- // requires (i.e. an L1 client)
7
- export class TXEArchiver extends ArchiverStoreHelper {
3
+ import { CheckpointNumber } from '@aztec/foundation/branded-types';
4
+ import { Fr } from '@aztec/foundation/curves/bn254';
5
+ /**
6
+ * TXE Archiver implementation.
7
+ * Provides most of the endpoints needed by the node for reading from and writing to state,
8
+ * without needing any of the extra overhead that the Archiver itself requires (i.e. an L1 client).
9
+ */ export class TXEArchiver extends ArchiverDataSourceBase {
10
+ updater = new ArchiverDataStoreUpdater(this.store);
8
11
  constructor(db){
9
- super(new KVArchiverDataStore(db, 9999));
12
+ const store = new KVArchiverDataStore(db, 9999, {
13
+ epochDuration: 32
14
+ });
15
+ super(store);
10
16
  }
11
- async addBlocks(blocks) {
12
- const opResults = await Promise.all([
13
- this.store.addLogs(blocks.map((block)=>block.block)),
14
- this.store.addBlocks(blocks)
15
- ]);
16
- return opResults.every(Boolean);
17
+ async addCheckpoints(checkpoints, result) {
18
+ await this.updater.addCheckpoints(checkpoints, result);
17
19
  }
18
- /**
19
- * Gets the number of the latest L2 block processed by the block source implementation.
20
- * @returns The number of the latest L2 block processed by the block source implementation.
21
- */ getBlockNumber() {
22
- return this.store.getSynchedL2BlockNumber();
20
+ getRollupAddress() {
21
+ throw new Error('TXE Archiver does not implement "getRollupAddress"');
23
22
  }
24
- /**
25
- * Gets the number of the latest L2 block proven seen by the block source implementation.
26
- * @returns The number of the latest L2 block proven seen by the block source implementation.
27
- */ getProvenBlockNumber() {
28
- return this.store.getSynchedL2BlockNumber();
23
+ getRegistryAddress() {
24
+ throw new Error('TXE Archiver does not implement "getRegistryAddress"');
29
25
  }
30
- /**
31
- * Gets a published l2 block. If a negative number is passed, the block returned is the most recent.
32
- * @param number - The block number to return (inclusive).
33
- * @returns The requested L2 block.
34
- */ async getPublishedBlock(number) {
35
- // If the number provided is -ve, then return the latest block.
36
- if (number < 0) {
37
- number = await this.store.getSynchedL2BlockNumber();
38
- }
39
- if (number == 0) {
40
- return undefined;
41
- }
42
- const blocks = await this.store.getPublishedBlocks(number, 1);
43
- return blocks.length === 0 ? undefined : blocks[0];
26
+ getL1Constants() {
27
+ throw new Error('TXE Archiver does not implement "getL1Constants"');
44
28
  }
45
- /**
46
- * Gets an l2 block. If a negative number is passed, the block returned is the most recent.
47
- * @param number - The block number to return (inclusive).
48
- * @returns The requested L2 block.
49
- */ getBlock(number) {
50
- return this.getPublishedBlock(number != 'latest' ? number : -1).then((block)=>block?.block);
29
+ getGenesisValues() {
30
+ return Promise.resolve({
31
+ genesisArchiveRoot: new Fr(GENESIS_ARCHIVE_ROOT)
32
+ });
51
33
  }
52
- /**
53
- * Gets an l2 block header.
54
- * @param number - The block number to return or 'latest' for the most recent one.
55
- * @returns The requested L2 block header.
56
- */ async getBlockHeader(number) {
57
- if (number === 'latest') {
58
- number = await this.store.getSynchedL2BlockNumber();
34
+ getL1Timestamp() {
35
+ throw new Error('TXE Archiver does not implement "getL1Timestamp"');
36
+ }
37
+ async getL2Tips() {
38
+ // In TXE there is no possibility of reorgs and no blocks are ever getting proven so we just set 'latest', 'proven'
39
+ // and 'finalized' to the latest block.
40
+ const blockHeader = await this.getBlockHeader('latest');
41
+ if (!blockHeader) {
42
+ throw new Error('L2Tips requested from TXE Archiver but no block header found');
59
43
  }
60
- if (number === 0) {
61
- return undefined;
44
+ const number = blockHeader.globalVariables.blockNumber;
45
+ const hash = (await blockHeader.hash()).toString();
46
+ const checkpointedBlock = await this.getCheckpointedBlock(number);
47
+ if (!checkpointedBlock) {
48
+ throw new Error(`L2Tips requested from TXE Archiver but no checkpointed block found for block number ${number}`);
62
49
  }
63
- const headers = await this.store.getBlockHeaders(number, 1);
64
- return headers.length === 0 ? undefined : headers[0];
65
- }
66
- getBlocks(from, limit, _proven) {
67
- return this.getPublishedBlocks(from, limit).then((blocks)=>blocks.map((b)=>b.block));
50
+ // TXE uses 1-block-per-checkpoint for testing simplicity, so we can use block number as checkpoint number.
51
+ // This uses the deprecated fromBlockNumber method intentionally for the TXE testing environment.
52
+ const checkpoint = await this.store.getRangeOfCheckpoints(CheckpointNumber.fromBlockNumber(number), 1);
53
+ if (checkpoint.length === 0) {
54
+ throw new Error(`L2Tips requested from TXE Archiver but no checkpoint found for block number ${number}`);
55
+ }
56
+ const blockId = {
57
+ number,
58
+ hash
59
+ };
60
+ const checkpointId = {
61
+ number: checkpoint[0].checkpointNumber,
62
+ hash: checkpoint[0].header.hash().toString()
63
+ };
64
+ const tipId = {
65
+ block: blockId,
66
+ checkpoint: checkpointId
67
+ };
68
+ return {
69
+ proposed: blockId,
70
+ proven: tipId,
71
+ finalized: tipId,
72
+ checkpointed: tipId
73
+ };
68
74
  }
69
75
  getL2SlotNumber() {
70
76
  throw new Error('TXE Archiver does not implement "getL2SlotNumber"');
@@ -72,47 +78,10 @@ export class TXEArchiver extends ArchiverStoreHelper {
72
78
  getL2EpochNumber() {
73
79
  throw new Error('TXE Archiver does not implement "getL2EpochNumber"');
74
80
  }
75
- getBlocksForEpoch(_epochNumber) {
76
- throw new Error('TXE Archiver does not implement "getBlocksForEpoch"');
77
- }
78
- getBlockHeadersForEpoch(_epochNumber) {
79
- throw new Error('TXE Archiver does not implement "getBlockHeadersForEpoch"');
80
- }
81
81
  isEpochComplete(_epochNumber) {
82
82
  throw new Error('TXE Archiver does not implement "isEpochComplete"');
83
83
  }
84
- getL2Tips() {
85
- throw new Error('TXE Archiver does not implement "getL2Tips"');
86
- }
87
- getL1Constants() {
88
- throw new Error('TXE Archiver does not implement "getL2Constants"');
89
- }
90
- getGenesisValues() {
91
- return Promise.resolve({
92
- genesisArchiveRoot: new Fr(GENESIS_ARCHIVE_ROOT)
93
- });
94
- }
95
84
  syncImmediate() {
96
85
  throw new Error('TXE Archiver does not implement "syncImmediate"');
97
86
  }
98
- getContract(_address, _timestamp) {
99
- throw new Error('TXE Archiver does not implement "getContract"');
100
- }
101
- getRollupAddress() {
102
- throw new Error('TXE Archiver does not implement "getRollupAddress"');
103
- }
104
- getRegistryAddress() {
105
- throw new Error('TXE Archiver does not implement "getRegistryAddress"');
106
- }
107
- getL1Timestamp() {
108
- throw new Error('TXE Archiver does not implement "getL1Timestamp"');
109
- }
110
- isPendingChainInvalid() {
111
- return Promise.resolve(false);
112
- }
113
- getPendingChainValidationStatus() {
114
- return Promise.resolve({
115
- valid: true
116
- });
117
- }
118
87
  }