@aztec/txe 0.0.1-commit.db765a8 → 0.0.1-commit.df81a97b5

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 (35) hide show
  1. package/dest/oracle/txe_oracle_top_level_context.d.ts +4 -3
  2. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  3. package/dest/oracle/txe_oracle_top_level_context.js +7 -2
  4. package/dest/rpc_translator.d.ts +12 -7
  5. package/dest/rpc_translator.d.ts.map +1 -1
  6. package/dest/rpc_translator.js +42 -13
  7. package/dest/state_machine/archiver.d.ts +3 -3
  8. package/dest/state_machine/archiver.d.ts.map +1 -1
  9. package/dest/state_machine/archiver.js +5 -7
  10. package/dest/state_machine/index.d.ts +4 -2
  11. package/dest/state_machine/index.d.ts.map +1 -1
  12. package/dest/state_machine/index.js +7 -3
  13. package/dest/state_machine/mock_epoch_cache.d.ts +17 -3
  14. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  15. package/dest/state_machine/mock_epoch_cache.js +32 -2
  16. package/dest/state_machine/synchronizer.d.ts +5 -5
  17. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  18. package/dest/state_machine/synchronizer.js +3 -3
  19. package/dest/txe_session.d.ts +4 -3
  20. package/dest/txe_session.d.ts.map +1 -1
  21. package/dest/txe_session.js +15 -6
  22. package/dest/util/encoding.d.ts +69 -1
  23. package/dest/util/encoding.d.ts.map +1 -1
  24. package/dest/util/txe_public_contract_data_source.d.ts +1 -1
  25. package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
  26. package/dest/util/txe_public_contract_data_source.js +1 -3
  27. package/package.json +15 -15
  28. package/src/oracle/txe_oracle_top_level_context.ts +5 -0
  29. package/src/rpc_translator.ts +59 -25
  30. package/src/state_machine/archiver.ts +5 -5
  31. package/src/state_machine/index.ts +6 -1
  32. package/src/state_machine/mock_epoch_cache.ts +42 -3
  33. package/src/state_machine/synchronizer.ts +4 -4
  34. package/src/txe_session.ts +14 -1
  35. package/src/util/txe_public_contract_data_source.ts +0 -2
@@ -652,34 +652,19 @@ export class RPCTranslator {
652
652
  }
653
653
 
654
654
  // eslint-disable-next-line camelcase
655
- public aztec_prv_notifyEnqueuedPublicFunctionCall(
656
- _foreignTargetContractAddress: ForeignCallSingle,
657
- _foreignCalldataHash: ForeignCallSingle,
658
- _foreignSideEffectCounter: ForeignCallSingle,
659
- _foreignIsStaticCall: ForeignCallSingle,
660
- ) {
661
- throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
662
- }
663
-
664
- // eslint-disable-next-line camelcase
665
- public aztec_prv_notifySetPublicTeardownFunctionCall(
666
- _foreignTargetContractAddress: ForeignCallSingle,
667
- _foreignCalldataHash: ForeignCallSingle,
668
- _foreignSideEffectCounter: ForeignCallSingle,
669
- _foreignIsStaticCall: ForeignCallSingle,
670
- ) {
655
+ public aztec_prv_validatePublicCalldata(_foreignCalldataHash: ForeignCallSingle) {
671
656
  throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
672
657
  }
673
658
 
674
659
  // eslint-disable-next-line camelcase
675
- public aztec_prv_notifySetMinRevertibleSideEffectCounter(_foreignMinRevertibleSideEffectCounter: ForeignCallSingle) {
660
+ public aztec_prv_notifyRevertiblePhaseStart(_foreignMinRevertibleSideEffectCounter: ForeignCallSingle) {
676
661
  throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
677
662
  }
678
663
 
679
664
  // eslint-disable-next-line camelcase
680
- public async aztec_prv_isSideEffectCounterRevertible(foreignSideEffectCounter: ForeignCallSingle) {
665
+ public async aztec_prv_inRevertiblePhase(foreignSideEffectCounter: ForeignCallSingle) {
681
666
  const sideEffectCounter = fromSingle(foreignSideEffectCounter).toNumber();
682
- const isRevertible = await this.handlerAsPrivate().isSideEffectCounterRevertible(sideEffectCounter);
667
+ const isRevertible = await this.handlerAsPrivate().inRevertiblePhase(sideEffectCounter);
683
668
  return toForeignCallResult([toSingle(new Fr(isRevertible))]);
684
669
  }
685
670
 
@@ -766,15 +751,21 @@ export class RPCTranslator {
766
751
  foreignContractAddress: ForeignCallSingle,
767
752
  foreignNoteValidationRequestsArrayBaseSlot: ForeignCallSingle,
768
753
  foreignEventValidationRequestsArrayBaseSlot: ForeignCallSingle,
754
+ foreignMaxNotePackedLen: ForeignCallSingle,
755
+ foreignMaxEventSerializedLen: ForeignCallSingle,
769
756
  ) {
770
757
  const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
771
758
  const noteValidationRequestsArrayBaseSlot = fromSingle(foreignNoteValidationRequestsArrayBaseSlot);
772
759
  const eventValidationRequestsArrayBaseSlot = fromSingle(foreignEventValidationRequestsArrayBaseSlot);
760
+ const maxNotePackedLen = fromSingle(foreignMaxNotePackedLen).toNumber();
761
+ const maxEventSerializedLen = fromSingle(foreignMaxEventSerializedLen).toNumber();
773
762
 
774
763
  await this.handlerAsUtility().validateAndStoreEnqueuedNotesAndEvents(
775
764
  contractAddress,
776
765
  noteValidationRequestsArrayBaseSlot,
777
766
  eventValidationRequestsArrayBaseSlot,
767
+ maxNotePackedLen,
768
+ maxEventSerializedLen,
778
769
  );
779
770
 
780
771
  return toForeignCallResult([]);
@@ -799,6 +790,25 @@ export class RPCTranslator {
799
790
  return toForeignCallResult([]);
800
791
  }
801
792
 
793
+ // eslint-disable-next-line camelcase
794
+ public async aztec_utl_utilityResolveMessageContexts(
795
+ foreignContractAddress: ForeignCallSingle,
796
+ foreignMessageContextRequestsArrayBaseSlot: ForeignCallSingle,
797
+ foreignMessageContextResponsesArrayBaseSlot: ForeignCallSingle,
798
+ ) {
799
+ const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
800
+ const messageContextRequestsArrayBaseSlot = fromSingle(foreignMessageContextRequestsArrayBaseSlot);
801
+ const messageContextResponsesArrayBaseSlot = fromSingle(foreignMessageContextResponsesArrayBaseSlot);
802
+
803
+ await this.handlerAsUtility().utilityResolveMessageContexts(
804
+ contractAddress,
805
+ messageContextRequestsArrayBaseSlot,
806
+ messageContextResponsesArrayBaseSlot,
807
+ );
808
+
809
+ return toForeignCallResult([]);
810
+ }
811
+
802
812
  // eslint-disable-next-line camelcase
803
813
  async aztec_utl_storeCapsule(
804
814
  foreignContractAddress: ForeignCallSingle,
@@ -869,7 +879,7 @@ export class RPCTranslator {
869
879
  // to implement this function here. Isn't there a way to programmatically identify that this is missing, given the
870
880
  // existence of a txe_oracle method?
871
881
  // eslint-disable-next-line camelcase
872
- async aztec_utl_aes128Decrypt(
882
+ async aztec_utl_tryAes128Decrypt(
873
883
  foreignCiphertextBVecStorage: ForeignCallArray,
874
884
  foreignCiphertextLength: ForeignCallSingle,
875
885
  foreignIv: ForeignCallArray,
@@ -879,11 +889,18 @@ export class RPCTranslator {
879
889
  const iv = fromUintArray(foreignIv, 8);
880
890
  const symKey = fromUintArray(foreignSymKey, 8);
881
891
 
882
- const plaintextBuffer = await this.handlerAsUtility().aes128Decrypt(ciphertext, iv, symKey);
883
-
884
- return toForeignCallResult(
885
- arrayToBoundedVec(bufferToU8Array(plaintextBuffer), foreignCiphertextBVecStorage.length),
886
- );
892
+ // Noir Option<BoundedVec> is encoded as [is_some: Field, storage: Field[], length: Field].
893
+ try {
894
+ const plaintextBuffer = await this.handlerAsUtility().aes128Decrypt(ciphertext, iv, symKey);
895
+ const [storage, length] = arrayToBoundedVec(
896
+ bufferToU8Array(plaintextBuffer),
897
+ foreignCiphertextBVecStorage.length,
898
+ );
899
+ return toForeignCallResult([toSingle(new Fr(1)), storage, length]);
900
+ } catch {
901
+ const zeroStorage = toArray(Array(foreignCiphertextBVecStorage.length).fill(new Fr(0)));
902
+ return toForeignCallResult([toSingle(new Fr(0)), zeroStorage, toSingle(new Fr(0))]);
903
+ }
887
904
  }
888
905
 
889
906
  // eslint-disable-next-line camelcase
@@ -905,6 +922,23 @@ export class RPCTranslator {
905
922
  return toForeignCallResult(secret.toFields().map(toSingle));
906
923
  }
907
924
 
925
+ // eslint-disable-next-line camelcase
926
+ aztec_utl_invalidateContractSyncCache(
927
+ foreignContractAddress: ForeignCallSingle,
928
+ foreignScopes: ForeignCallArray,
929
+ foreignScopeCount: ForeignCallSingle,
930
+ ) {
931
+ const contractAddress = addressFromSingle(foreignContractAddress);
932
+ const count = fromSingle(foreignScopeCount).toNumber();
933
+ const scopes = fromArray(foreignScopes)
934
+ .slice(0, count)
935
+ .map(f => new AztecAddress(f));
936
+
937
+ this.handlerAsUtility().invalidateContractSyncCache(contractAddress, scopes);
938
+
939
+ return Promise.resolve(toForeignCallResult([]));
940
+ }
941
+
908
942
  // eslint-disable-next-line camelcase
909
943
  aztec_utl_emitOffchainEffect(_foreignData: ForeignCallArray) {
910
944
  throw new Error('Offchain effects are not yet supported in the TestEnvironment');
@@ -17,7 +17,7 @@ export class TXEArchiver extends ArchiverDataSourceBase {
17
17
  private readonly updater = new ArchiverDataStoreUpdater(this.store);
18
18
 
19
19
  constructor(db: AztecAsyncKVStore) {
20
- const store = new KVArchiverDataStore(db, 9999, { epochDuration: 32 });
20
+ const store = new KVArchiverDataStore(db, 9999);
21
21
  super(store);
22
22
  }
23
23
 
@@ -79,12 +79,12 @@ export class TXEArchiver extends ArchiverDataSourceBase {
79
79
  };
80
80
  }
81
81
 
82
- public getL2SlotNumber(): Promise<SlotNumber | undefined> {
83
- throw new Error('TXE Archiver does not implement "getL2SlotNumber"');
82
+ public getSyncedL2SlotNumber(): Promise<SlotNumber | undefined> {
83
+ throw new Error('TXE Archiver does not implement "getSyncedL2SlotNumber"');
84
84
  }
85
85
 
86
- public getL2EpochNumber(): Promise<EpochNumber | undefined> {
87
- throw new Error('TXE Archiver does not implement "getL2EpochNumber"');
86
+ public getSyncedL2EpochNumber(): Promise<EpochNumber | undefined> {
87
+ throw new Error('TXE Archiver does not implement "getSyncedL2EpochNumber"');
88
88
  }
89
89
 
90
90
  public isEpochComplete(_epochNumber: EpochNumber): Promise<boolean> {
@@ -4,6 +4,7 @@ import { CheckpointNumber } from '@aztec/foundation/branded-types';
4
4
  import { Fr } from '@aztec/foundation/curves/bn254';
5
5
  import { createLogger } from '@aztec/foundation/log';
6
6
  import { type AnchorBlockStore, type ContractStore, ContractSyncService, type NoteStore } from '@aztec/pxe/server';
7
+ import { MessageContextService } from '@aztec/pxe/simulator';
7
8
  import { L2Block } from '@aztec/stdlib/block';
8
9
  import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
9
10
  import type { AztecNode } from '@aztec/stdlib/interfaces/client';
@@ -26,6 +27,7 @@ export class TXEStateMachine {
26
27
  public archiver: TXEArchiver,
27
28
  public anchorBlockStore: AnchorBlockStore,
28
29
  public contractSyncService: ContractSyncService,
30
+ public messageContextService: MessageContextService,
29
31
  ) {}
30
32
 
31
33
  public static async create(
@@ -57,6 +59,7 @@ export class TXEStateMachine {
57
59
  new MockEpochCache(),
58
60
  getPackageVersion() ?? '',
59
61
  new TestCircuitVerifier(),
62
+ new TestCircuitVerifier(),
60
63
  undefined,
61
64
  log,
62
65
  );
@@ -68,7 +71,9 @@ export class TXEStateMachine {
68
71
  createLogger('txe:contract_sync'),
69
72
  );
70
73
 
71
- return new this(node, synchronizer, archiver, anchorBlockStore, contractSyncService);
74
+ const messageContextService = new MessageContextService(node);
75
+
76
+ return new this(node, synchronizer, archiver, anchorBlockStore, contractSyncService, messageContextService);
72
77
  }
73
78
 
74
79
  public async handleL2Block(block: L2Block) {
@@ -8,7 +8,7 @@ import { EmptyL1RollupConstants, type L1RollupConstants } from '@aztec/stdlib/ep
8
8
  * Since in TXE we don't validate transactions, mock suffices here.
9
9
  */
10
10
  export class MockEpochCache implements EpochCacheInterface {
11
- getCommittee(): Promise<EpochCommitteeInfo> {
11
+ getCommittee(_slot: SlotTag = 'now'): Promise<EpochCommitteeInfo> {
12
12
  return Promise.resolve({
13
13
  committee: undefined,
14
14
  seed: 0n,
@@ -17,6 +17,22 @@ export class MockEpochCache implements EpochCacheInterface {
17
17
  });
18
18
  }
19
19
 
20
+ getSlotNow(): SlotNumber {
21
+ return SlotNumber(0);
22
+ }
23
+
24
+ getTargetSlot(): SlotNumber {
25
+ return SlotNumber(0);
26
+ }
27
+
28
+ getEpochNow(): EpochNumber {
29
+ return EpochNumber.ZERO;
30
+ }
31
+
32
+ getTargetEpoch(): EpochNumber {
33
+ return EpochNumber.ZERO;
34
+ }
35
+
20
36
  getEpochAndSlotNow(): EpochAndSlot & { nowMs: bigint } {
21
37
  return {
22
38
  epoch: EpochNumber.ZERO,
@@ -26,15 +42,23 @@ export class MockEpochCache implements EpochCacheInterface {
26
42
  };
27
43
  }
28
44
 
29
- getEpochAndSlotInNextL1Slot(): EpochAndSlot & { now: bigint } {
45
+ getEpochAndSlotInNextL1Slot(): EpochAndSlot & { nowSeconds: bigint } {
30
46
  return {
31
47
  epoch: EpochNumber.ZERO,
32
48
  slot: SlotNumber(0),
33
49
  ts: 0n,
34
- now: 0n,
50
+ nowSeconds: 0n,
35
51
  };
36
52
  }
37
53
 
54
+ getTargetEpochAndSlotInNextL1Slot(): EpochAndSlot & { nowSeconds: bigint } {
55
+ return this.getEpochAndSlotInNextL1Slot();
56
+ }
57
+
58
+ isProposerPipeliningEnabled(): boolean {
59
+ return false;
60
+ }
61
+
38
62
  getProposerIndexEncoding(_epoch: EpochNumber, _slot: SlotNumber, _seed: bigint): `0x${string}` {
39
63
  return '0x00';
40
64
  }
@@ -50,6 +74,13 @@ export class MockEpochCache implements EpochCacheInterface {
50
74
  };
51
75
  }
52
76
 
77
+ getTargetAndNextSlot(): { targetSlot: SlotNumber; nextSlot: SlotNumber } {
78
+ return {
79
+ targetSlot: SlotNumber(0),
80
+ nextSlot: SlotNumber(0),
81
+ };
82
+ }
83
+
53
84
  getProposerAttesterAddressInSlot(_slot: SlotNumber): Promise<EthAddress | undefined> {
54
85
  return Promise.resolve(undefined);
55
86
  }
@@ -66,6 +97,14 @@ export class MockEpochCache implements EpochCacheInterface {
66
97
  return Promise.resolve([]);
67
98
  }
68
99
 
100
+ isEscapeHatchOpen(_epoch: EpochNumber): Promise<boolean> {
101
+ return Promise.resolve(false);
102
+ }
103
+
104
+ isEscapeHatchOpenAtSlot(_slot: SlotTag): Promise<boolean> {
105
+ return Promise.resolve(false);
106
+ }
107
+
69
108
  getL1Constants(): L1RollupConstants {
70
109
  return EmptyL1RollupConstants;
71
110
  }
@@ -1,7 +1,7 @@
1
1
  import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
2
2
  import { BlockNumber } from '@aztec/foundation/branded-types';
3
3
  import { Fr } from '@aztec/foundation/curves/bn254';
4
- import type { L2Block } from '@aztec/stdlib/block';
4
+ import type { BlockHash, L2Block } from '@aztec/stdlib/block';
5
5
  import type {
6
6
  MerkleTreeReadOperations,
7
7
  MerkleTreeWriteOperations,
@@ -33,12 +33,12 @@ export class TXESynchronizer implements WorldStateSynchronizer {
33
33
  }
34
34
 
35
35
  /**
36
- * Forces an immediate sync to an optionally provided minimum block number
36
+ * Forces an immediate sync to an optionally provided minimum block number.
37
37
  * @param targetBlockNumber - The target block number that we must sync to. Will download unproven blocks if needed to reach it.
38
- * @param skipThrowIfTargetNotReached - Whether to skip throwing if the target block number is not reached.
38
+ * @param blockHash - If provided, verifies the block at targetBlockNumber matches this hash.
39
39
  * @returns A promise that resolves with the block number the world state was synced to
40
40
  */
41
- public syncImmediate(_minBlockNumber?: BlockNumber, _skipThrowIfTargetNotReached?: boolean): Promise<BlockNumber> {
41
+ public syncImmediate(_minBlockNumber?: BlockNumber, _blockHash?: BlockHash): Promise<BlockNumber> {
42
42
  return Promise.resolve(this.blockNumber);
43
43
  }
44
44
 
@@ -9,6 +9,7 @@ import {
9
9
  AnchorBlockStore,
10
10
  CapsuleStore,
11
11
  ContractStore,
12
+ ContractSyncService,
12
13
  JobCoordinator,
13
14
  NoteService,
14
15
  NoteStore,
@@ -150,6 +151,7 @@ export class TXESession implements TXESessionStateHandler {
150
151
  private chainId: Fr,
151
152
  private version: Fr,
152
153
  private nextBlockTimestamp: bigint,
154
+ private contractSyncService: ContractSyncService,
153
155
  ) {}
154
156
 
155
157
  static async init(contractStore: ContractStore) {
@@ -185,6 +187,9 @@ export class TXESession implements TXESessionStateHandler {
185
187
 
186
188
  const initialJobId = jobCoordinator.beginJob();
187
189
 
190
+ const logger = createLogger('txe:session');
191
+ const contractSyncService = new ContractSyncService(stateMachine.node, contractStore, noteStore, logger);
192
+
188
193
  const topLevelOracleHandler = new TXEOracleTopLevelContext(
189
194
  stateMachine,
190
195
  contractStore,
@@ -201,11 +206,12 @@ export class TXESession implements TXESessionStateHandler {
201
206
  version,
202
207
  chainId,
203
208
  new Map(),
209
+ contractSyncService,
204
210
  );
205
211
  await topLevelOracleHandler.advanceBlocksBy(1);
206
212
 
207
213
  return new TXESession(
208
- createLogger('txe:session'),
214
+ logger,
209
215
  stateMachine,
210
216
  topLevelOracleHandler,
211
217
  contractStore,
@@ -223,6 +229,7 @@ export class TXESession implements TXESessionStateHandler {
223
229
  version,
224
230
  chainId,
225
231
  nextBlockTimestamp,
232
+ contractSyncService,
226
233
  );
227
234
  }
228
235
 
@@ -309,6 +316,7 @@ export class TXESession implements TXESessionStateHandler {
309
316
  this.version,
310
317
  this.chainId,
311
318
  this.authwits,
319
+ this.contractSyncService,
312
320
  );
313
321
 
314
322
  this.state = { name: 'TOP_LEVEL' };
@@ -369,6 +377,7 @@ export class TXESession implements TXESessionStateHandler {
369
377
  contractSyncService: this.stateMachine.contractSyncService,
370
378
  jobId: this.currentJobId,
371
379
  scopes: 'ALL_SCOPES',
380
+ messageContextService: this.stateMachine.messageContextService,
372
381
  });
373
382
 
374
383
  // We store the note and tagging index caches fed into the PrivateExecutionOracle (along with some other auxiliary
@@ -437,6 +446,8 @@ export class TXESession implements TXESessionStateHandler {
437
446
  senderAddressBookStore: this.senderAddressBookStore,
438
447
  capsuleStore: this.capsuleStore,
439
448
  privateEventStore: this.privateEventStore,
449
+ messageContextService: this.stateMachine.messageContextService,
450
+ contractSyncService: this.contractSyncService,
440
451
  jobId: this.currentJobId,
441
452
  scopes: 'ALL_SCOPES',
442
453
  });
@@ -528,6 +539,8 @@ export class TXESession implements TXESessionStateHandler {
528
539
  senderAddressBookStore: this.senderAddressBookStore,
529
540
  capsuleStore: this.capsuleStore,
530
541
  privateEventStore: this.privateEventStore,
542
+ messageContextService: this.stateMachine.messageContextService,
543
+ contractSyncService: this.contractSyncService,
531
544
  jobId: this.currentJobId,
532
545
  scopes,
533
546
  });
@@ -26,8 +26,6 @@ export class TXEPublicContractDataSource implements ContractDataSource {
26
26
  packedBytecode: contractClass.packedBytecode,
27
27
  privateFunctionsRoot: contractClass.privateFunctionsRoot,
28
28
  version: contractClass.version,
29
- privateFunctions: [],
30
- utilityFunctions: [],
31
29
  };
32
30
  }
33
31