@aztec/txe 0.0.1-commit.1bb068fb5 → 0.0.1-commit.1dcfe2301

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 (60) hide show
  1. package/dest/index.d.ts +1 -1
  2. package/dest/index.d.ts.map +1 -1
  3. package/dest/index.js +88 -54
  4. package/dest/oracle/interfaces.d.ts +29 -28
  5. package/dest/oracle/interfaces.d.ts.map +1 -1
  6. package/dest/oracle/txe_oracle_public_context.d.ts +13 -13
  7. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  8. package/dest/oracle/txe_oracle_public_context.js +12 -12
  9. package/dest/oracle/txe_oracle_top_level_context.d.ts +28 -23
  10. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  11. package/dest/oracle/txe_oracle_top_level_context.js +78 -51
  12. package/dest/rpc_translator.d.ts +120 -82
  13. package/dest/rpc_translator.d.ts.map +1 -1
  14. package/dest/rpc_translator.js +384 -162
  15. package/dest/state_machine/archiver.d.ts +3 -3
  16. package/dest/state_machine/archiver.d.ts.map +1 -1
  17. package/dest/state_machine/archiver.js +7 -8
  18. package/dest/state_machine/dummy_p2p_client.d.ts +8 -6
  19. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  20. package/dest/state_machine/dummy_p2p_client.js +12 -6
  21. package/dest/state_machine/global_variable_builder.d.ts +9 -4
  22. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  23. package/dest/state_machine/global_variable_builder.js +9 -3
  24. package/dest/state_machine/index.d.ts +4 -2
  25. package/dest/state_machine/index.d.ts.map +1 -1
  26. package/dest/state_machine/index.js +8 -4
  27. package/dest/state_machine/mock_epoch_cache.d.ts +18 -3
  28. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  29. package/dest/state_machine/mock_epoch_cache.js +35 -2
  30. package/dest/state_machine/synchronizer.d.ts +5 -5
  31. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  32. package/dest/state_machine/synchronizer.js +3 -3
  33. package/dest/txe_session.d.ts +10 -6
  34. package/dest/txe_session.d.ts.map +1 -1
  35. package/dest/txe_session.js +37 -25
  36. package/dest/util/encoding.d.ts +71 -1
  37. package/dest/util/encoding.d.ts.map +1 -1
  38. package/dest/util/encoding.js +4 -0
  39. package/dest/util/txe_public_contract_data_source.d.ts +2 -3
  40. package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
  41. package/dest/util/txe_public_contract_data_source.js +6 -25
  42. package/package.json +15 -15
  43. package/src/index.ts +89 -52
  44. package/src/oracle/interfaces.ts +32 -31
  45. package/src/oracle/txe_oracle_public_context.ts +12 -12
  46. package/src/oracle/txe_oracle_top_level_context.ts +99 -56
  47. package/src/rpc_translator.ts +446 -183
  48. package/src/state_machine/archiver.ts +6 -5
  49. package/src/state_machine/dummy_p2p_client.ts +17 -9
  50. package/src/state_machine/global_variable_builder.ts +18 -3
  51. package/src/state_machine/index.ts +9 -2
  52. package/src/state_machine/mock_epoch_cache.ts +46 -3
  53. package/src/state_machine/synchronizer.ts +4 -4
  54. package/src/txe_session.ts +48 -28
  55. package/src/util/encoding.ts +5 -0
  56. package/src/util/txe_public_contract_data_source.ts +10 -38
  57. package/dest/util/txe_contract_store.d.ts +0 -12
  58. package/dest/util/txe_contract_store.d.ts.map +0 -1
  59. package/dest/util/txe_contract_store.js +0 -22
  60. package/src/util/txe_contract_store.ts +0 -36
@@ -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
 
@@ -76,15 +76,16 @@ export class TXEArchiver extends ArchiverDataSourceBase {
76
76
  proven: tipId,
77
77
  finalized: tipId,
78
78
  checkpointed: tipId,
79
+ proposedCheckpoint: tipId,
79
80
  };
80
81
  }
81
82
 
82
- public getL2SlotNumber(): Promise<SlotNumber | undefined> {
83
- throw new Error('TXE Archiver does not implement "getL2SlotNumber"');
83
+ public getSyncedL2SlotNumber(): Promise<SlotNumber | undefined> {
84
+ throw new Error('TXE Archiver does not implement "getSyncedL2SlotNumber"');
84
85
  }
85
86
 
86
- public getL2EpochNumber(): Promise<EpochNumber | undefined> {
87
- throw new Error('TXE Archiver does not implement "getL2EpochNumber"');
87
+ public getSyncedL2EpochNumber(): Promise<EpochNumber | undefined> {
88
+ throw new Error('TXE Archiver does not implement "getSyncedL2EpochNumber"');
88
89
  }
89
90
 
90
91
  public isEpochComplete(_epochNumber: EpochNumber): Promise<boolean> {
@@ -16,12 +16,12 @@ import type {
16
16
  StatusMessage,
17
17
  } from '@aztec/p2p';
18
18
  import type { EthAddress, L2BlockStreamEvent, L2Tips } from '@aztec/stdlib/block';
19
- import type { PeerInfo } from '@aztec/stdlib/interfaces/server';
20
- import type { BlockProposal, CheckpointAttestation, CheckpointProposal } from '@aztec/stdlib/p2p';
19
+ import type { ITxProvider, PeerInfo } from '@aztec/stdlib/interfaces/server';
20
+ import type { BlockProposal, CheckpointAttestation, CheckpointProposal, TopicType } from '@aztec/stdlib/p2p';
21
21
  import type { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx';
22
22
 
23
23
  export class DummyP2P implements P2P {
24
- public validate(_txs: Tx[]): Promise<void> {
24
+ public validateTxsReceivedInBlockProposal(_txs: Tx[]): Promise<void> {
25
25
  return Promise.resolve();
26
26
  }
27
27
 
@@ -41,6 +41,10 @@ export class DummyP2P implements P2P {
41
41
  throw new Error('DummyP2P does not implement "getPeers"');
42
42
  }
43
43
 
44
+ public getGossipMeshPeerCount(_topicType: TopicType): Promise<number> {
45
+ return Promise.resolve(0);
46
+ }
47
+
44
48
  public broadcastProposal(_proposal: BlockProposal): Promise<void> {
45
49
  throw new Error('DummyP2P does not implement "broadcastProposal"');
46
50
  }
@@ -57,8 +61,12 @@ export class DummyP2P implements P2P {
57
61
  throw new Error('DummyP2P does not implement "registerBlockProposalHandler"');
58
62
  }
59
63
 
60
- public registerCheckpointProposalHandler(_handler: P2PCheckpointReceivedCallback): void {
61
- throw new Error('DummyP2P does not implement "registerCheckpointProposalHandler"');
64
+ public registerValidatorCheckpointProposalHandler(_handler: P2PCheckpointReceivedCallback): void {
65
+ throw new Error('DummyP2P does not implement "registerValidatorCheckpointProposalHandler"');
66
+ }
67
+
68
+ public registerAllNodesCheckpointProposalHandler(_handler: P2PCheckpointReceivedCallback): void {
69
+ throw new Error('DummyP2P does not implement "registerAllNodesCheckpointProposalHandler"');
62
70
  }
63
71
 
64
72
  public requestTxs(_txHashes: TxHash[]): Promise<(Tx | undefined)[]> {
@@ -131,6 +139,10 @@ export class DummyP2P implements P2P {
131
139
  throw new Error('DummyP2P does not implement "isP2PClient"');
132
140
  }
133
141
 
142
+ public getTxProvider(): ITxProvider {
143
+ throw new Error('DummyP2P does not implement "getTxProvider"');
144
+ }
145
+
134
146
  public getTxsByHash(_txHashes: TxHash[]): Promise<Tx[]> {
135
147
  throw new Error('DummyP2P does not implement "getTxsByHash"');
136
148
  }
@@ -171,10 +183,6 @@ export class DummyP2P implements P2P {
171
183
  throw new Error('DummyP2P does not implement "hasTxsInPool"');
172
184
  }
173
185
 
174
- public addTxsToPool(_txs: Tx[]): Promise<number> {
175
- throw new Error('DummyP2P does not implement "addTxs"');
176
- }
177
-
178
186
  public getSyncedLatestBlockNum(): Promise<number> {
179
187
  throw new Error('DummyP2P does not implement "getSyncedLatestBlockNum"');
180
188
  }
@@ -1,15 +1,29 @@
1
+ import type { SimulationOverridesPlan } from '@aztec/ethereum/contracts';
1
2
  import { BlockNumber, type SlotNumber } from '@aztec/foundation/branded-types';
3
+ import { times } from '@aztec/foundation/collection';
2
4
  import type { EthAddress } from '@aztec/foundation/eth-address';
3
5
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
4
- import { GasFees } from '@aztec/stdlib/gas';
6
+ import { FEE_ORACLE_LAG, GasFees } from '@aztec/stdlib/gas';
5
7
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
6
- import { type CheckpointGlobalVariables, type GlobalVariableBuilder, GlobalVariables } from '@aztec/stdlib/tx';
8
+ import {
9
+ type CheckpointGlobalVariables,
10
+ type FeeProvider,
11
+ type GlobalVariableBuilder,
12
+ GlobalVariables,
13
+ } from '@aztec/stdlib/tx';
7
14
 
8
- export class TXEGlobalVariablesBuilder implements GlobalVariableBuilder {
15
+ /** Simple FeeProvider for TXE that returns zero fees. */
16
+ export class TXEFeeProvider implements FeeProvider {
9
17
  public getCurrentMinFees(): Promise<GasFees> {
10
18
  return Promise.resolve(new GasFees(0, 0));
11
19
  }
12
20
 
21
+ public getPredictedMinFees(): Promise<GasFees[]> {
22
+ return Promise.resolve(times(FEE_ORACLE_LAG, () => new GasFees(0, 0)));
23
+ }
24
+ }
25
+
26
+ export class TXEGlobalVariablesBuilder implements GlobalVariableBuilder {
13
27
  public buildGlobalVariables(
14
28
  _blockNumber: BlockNumber,
15
29
  _coinbase: EthAddress,
@@ -23,6 +37,7 @@ export class TXEGlobalVariablesBuilder implements GlobalVariableBuilder {
23
37
  _coinbase: EthAddress,
24
38
  _feeRecipient: AztecAddress,
25
39
  _slotNumber: SlotNumber,
40
+ _simulationOverridesPlan?: SimulationOverridesPlan,
26
41
  ): Promise<CheckpointGlobalVariables> {
27
42
  const vars = makeGlobalVariables();
28
43
  return Promise.resolve({
@@ -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';
@@ -12,7 +13,7 @@ import { getPackageVersion } from '@aztec/stdlib/update-checker';
12
13
 
13
14
  import { TXEArchiver } from './archiver.js';
14
15
  import { DummyP2P } from './dummy_p2p_client.js';
15
- import { TXEGlobalVariablesBuilder } from './global_variable_builder.js';
16
+ import { TXEFeeProvider, TXEGlobalVariablesBuilder } from './global_variable_builder.js';
16
17
  import { MockEpochCache } from './mock_epoch_cache.js';
17
18
  import { TXESynchronizer } from './synchronizer.js';
18
19
 
@@ -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(
@@ -50,12 +52,15 @@ export class TXEStateMachine {
50
52
  undefined,
51
53
  undefined,
52
54
  undefined,
55
+ undefined,
53
56
  VERSION,
54
57
  CHAIN_ID,
55
58
  new TXEGlobalVariablesBuilder(),
59
+ new TXEFeeProvider(),
56
60
  new MockEpochCache(),
57
61
  getPackageVersion() ?? '',
58
62
  new TestCircuitVerifier(),
63
+ new TestCircuitVerifier(),
59
64
  undefined,
60
65
  log,
61
66
  );
@@ -67,7 +72,9 @@ export class TXEStateMachine {
67
72
  createLogger('txe:contract_sync'),
68
73
  );
69
74
 
70
- return new this(node, synchronizer, archiver, anchorBlockStore, contractSyncService);
75
+ const messageContextService = new MessageContextService(node);
76
+
77
+ return new this(node, synchronizer, archiver, anchorBlockStore, contractSyncService, messageContextService);
71
78
  }
72
79
 
73
80
  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,27 @@ 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
+
62
+ pipeliningOffset(): number {
63
+ return 0;
64
+ }
65
+
38
66
  getProposerIndexEncoding(_epoch: EpochNumber, _slot: SlotNumber, _seed: bigint): `0x${string}` {
39
67
  return '0x00';
40
68
  }
@@ -50,6 +78,13 @@ export class MockEpochCache implements EpochCacheInterface {
50
78
  };
51
79
  }
52
80
 
81
+ getTargetAndNextSlot(): { targetSlot: SlotNumber; nextSlot: SlotNumber } {
82
+ return {
83
+ targetSlot: SlotNumber(0),
84
+ nextSlot: SlotNumber(0),
85
+ };
86
+ }
87
+
53
88
  getProposerAttesterAddressInSlot(_slot: SlotNumber): Promise<EthAddress | undefined> {
54
89
  return Promise.resolve(undefined);
55
90
  }
@@ -66,6 +101,14 @@ export class MockEpochCache implements EpochCacheInterface {
66
101
  return Promise.resolve([]);
67
102
  }
68
103
 
104
+ isEscapeHatchOpen(_epoch: EpochNumber): Promise<boolean> {
105
+ return Promise.resolve(false);
106
+ }
107
+
108
+ isEscapeHatchOpenAtSlot(_slot: SlotTag): Promise<boolean> {
109
+ return Promise.resolve(false);
110
+ }
111
+
69
112
  getL1Constants(): L1RollupConstants {
70
113
  return EmptyL1RollupConstants;
71
114
  }
@@ -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
 
@@ -3,12 +3,13 @@ import { Fr } from '@aztec/foundation/curves/bn254';
3
3
  import { type Logger, createLogger } from '@aztec/foundation/log';
4
4
  import { KeyStore } from '@aztec/key-store';
5
5
  import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
6
- import type { ProtocolContract } from '@aztec/protocol-contracts';
7
- import type { AccessScopes } from '@aztec/pxe/client/lazy';
8
6
  import {
9
7
  AddressStore,
10
8
  AnchorBlockStore,
9
+ CapsuleService,
11
10
  CapsuleStore,
11
+ ContractStore,
12
+ ContractSyncService,
12
13
  JobCoordinator,
13
14
  NoteService,
14
15
  NoteStore,
@@ -55,7 +56,6 @@ import { TXEArchiver } from './state_machine/archiver.js';
55
56
  import { TXEStateMachine } from './state_machine/index.js';
56
57
  import type { ForeignCallArgs, ForeignCallResult } from './util/encoding.js';
57
58
  import { TXEAccountStore } from './util/txe_account_store.js';
58
- import { TXEContractStore } from './util/txe_contract_store.js';
59
59
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from './utils/block_creation.js';
60
60
  import { makeTxEffect } from './utils/tx_effect_creation.js';
61
61
 
@@ -114,6 +114,10 @@ export interface TXESessionStateHandler {
114
114
  enterPublicState(contractAddress?: AztecAddress): Promise<void>;
115
115
  enterPrivateState(contractAddress?: AztecAddress, anchorBlockNumber?: BlockNumber): Promise<PrivateContextInputs>;
116
116
  enterUtilityState(contractAddress?: AztecAddress): Promise<void>;
117
+
118
+ // TODO(F-335): Exposing the job info is abstraction breakage - drop the following 2 functions.
119
+ cycleJob(): Promise<string>;
120
+ getCurrentJob(): string;
117
121
  }
118
122
 
119
123
  /**
@@ -132,7 +136,7 @@ export class TXESession implements TXESessionStateHandler {
132
136
  | IPrivateExecutionOracle
133
137
  | IAvmExecutionOracle
134
138
  | ITxeExecutionOracle,
135
- private contractStore: TXEContractStore,
139
+ private contractStore: ContractStore,
136
140
  private noteStore: NoteStore,
137
141
  private keyStore: KeyStore,
138
142
  private addressStore: AddressStore,
@@ -147,14 +151,14 @@ export class TXESession implements TXESessionStateHandler {
147
151
  private chainId: Fr,
148
152
  private version: Fr,
149
153
  private nextBlockTimestamp: bigint,
154
+ private contractSyncService: ContractSyncService,
150
155
  ) {}
151
156
 
152
- static async init(protocolContracts: ProtocolContract[]) {
157
+ static async init(contractStore: ContractStore) {
153
158
  const store = await openTmpStore('txe-session');
154
159
 
155
160
  const addressStore = new AddressStore(store);
156
161
  const privateEventStore = new PrivateEventStore(store);
157
- const contractStore = new TXEContractStore(store);
158
162
  const noteStore = new NoteStore(store);
159
163
  const senderTaggingStore = new SenderTaggingStore(store);
160
164
  const recipientTaggingStore = new RecipientTaggingStore(store);
@@ -173,12 +177,6 @@ export class TXESession implements TXESessionStateHandler {
173
177
  noteStore,
174
178
  ]);
175
179
 
176
- // Register protocol contracts.
177
- for (const { contractClass, instance, artifact } of protocolContracts) {
178
- await contractStore.addContractArtifact(contractClass.id, artifact);
179
- await contractStore.addContractInstance(instance);
180
- }
181
-
182
180
  const archiver = new TXEArchiver(store);
183
181
  const anchorBlockStore = new AnchorBlockStore(store);
184
182
  const stateMachine = await TXEStateMachine.create(archiver, anchorBlockStore, contractStore, noteStore);
@@ -189,6 +187,9 @@ export class TXESession implements TXESessionStateHandler {
189
187
 
190
188
  const initialJobId = jobCoordinator.beginJob();
191
189
 
190
+ const logger = createLogger('txe:session');
191
+ const contractSyncService = new ContractSyncService(stateMachine.node, contractStore, noteStore, logger);
192
+
192
193
  const topLevelOracleHandler = new TXEOracleTopLevelContext(
193
194
  stateMachine,
194
195
  contractStore,
@@ -201,16 +202,16 @@ export class TXESession implements TXESessionStateHandler {
201
202
  senderAddressBookStore,
202
203
  capsuleStore,
203
204
  privateEventStore,
204
- initialJobId,
205
205
  nextBlockTimestamp,
206
206
  version,
207
207
  chainId,
208
208
  new Map(),
209
+ contractSyncService,
209
210
  );
210
- await topLevelOracleHandler.txeAdvanceBlocksBy(1);
211
+ await topLevelOracleHandler.advanceBlocksBy(1);
211
212
 
212
213
  return new TXESession(
213
- createLogger('txe:session'),
214
+ logger,
214
215
  stateMachine,
215
216
  topLevelOracleHandler,
216
217
  contractStore,
@@ -228,6 +229,7 @@ export class TXESession implements TXESessionStateHandler {
228
229
  version,
229
230
  chainId,
230
231
  nextBlockTimestamp,
232
+ contractSyncService,
231
233
  );
232
234
  }
233
235
 
@@ -262,6 +264,17 @@ export class TXESession implements TXESessionStateHandler {
262
264
  }
263
265
  }
264
266
 
267
+ getCurrentJob(): string {
268
+ return this.currentJobId;
269
+ }
270
+
271
+ /** Commits the current job and begins a new one. Returns the new job ID. */
272
+ async cycleJob(): Promise<string> {
273
+ await this.jobCoordinator.commitJob(this.currentJobId);
274
+ this.currentJobId = this.jobCoordinator.beginJob();
275
+ return this.currentJobId;
276
+ }
277
+
265
278
  async enterTopLevelState() {
266
279
  switch (this.state.name) {
267
280
  case 'PRIVATE': {
@@ -285,8 +298,7 @@ export class TXESession implements TXESessionStateHandler {
285
298
  }
286
299
 
287
300
  // Commit all staged stores from the job that was just completed, then begin a new job
288
- await this.jobCoordinator.commitJob(this.currentJobId);
289
- this.currentJobId = this.jobCoordinator.beginJob();
301
+ await this.cycleJob();
290
302
 
291
303
  this.oracleHandler = new TXEOracleTopLevelContext(
292
304
  this.stateMachine,
@@ -300,11 +312,11 @@ export class TXESession implements TXESessionStateHandler {
300
312
  this.senderAddressBookStore,
301
313
  this.capsuleStore,
302
314
  this.privateEventStore,
303
- this.currentJobId,
304
315
  this.nextBlockTimestamp,
305
316
  this.version,
306
317
  this.chainId,
307
318
  this.authwits,
319
+ this.contractSyncService,
308
320
  );
309
321
 
310
322
  this.state = { name: 'TOP_LEVEL' };
@@ -324,7 +336,7 @@ export class TXESession implements TXESessionStateHandler {
324
336
 
325
337
  await new NoteService(this.noteStore, this.stateMachine.node, anchorBlock!, this.currentJobId).syncNoteNullifiers(
326
338
  contractAddress,
327
- 'ALL_SCOPES',
339
+ await this.keyStore.getAccounts(),
328
340
  );
329
341
  const latestBlock = await this.stateMachine.node.getBlockHeader('latest');
330
342
 
@@ -360,11 +372,13 @@ export class TXESession implements TXESessionStateHandler {
360
372
  senderTaggingStore: this.senderTaggingStore,
361
373
  recipientTaggingStore: this.recipientTaggingStore,
362
374
  senderAddressBookStore: this.senderAddressBookStore,
363
- capsuleStore: this.capsuleStore,
375
+ capsuleService: new CapsuleService(this.capsuleStore, await this.keyStore.getAccounts()),
364
376
  privateEventStore: this.privateEventStore,
365
377
  contractSyncService: this.stateMachine.contractSyncService,
378
+ l2TipsStore: this.stateMachine.node,
366
379
  jobId: this.currentJobId,
367
- scopes: 'ALL_SCOPES',
380
+ scopes: await this.keyStore.getAccounts(),
381
+ messageContextService: this.stateMachine.messageContextService,
368
382
  });
369
383
 
370
384
  // We store the note and tagging index caches fed into the PrivateExecutionOracle (along with some other auxiliary
@@ -417,7 +431,7 @@ export class TXESession implements TXESessionStateHandler {
417
431
  this.stateMachine.node,
418
432
  anchorBlockHeader,
419
433
  this.currentJobId,
420
- ).syncNoteNullifiers(contractAddress, 'ALL_SCOPES');
434
+ ).syncNoteNullifiers(contractAddress, await this.keyStore.getAccounts());
421
435
 
422
436
  this.oracleHandler = new UtilityExecutionOracle({
423
437
  contractAddress,
@@ -431,10 +445,13 @@ export class TXESession implements TXESessionStateHandler {
431
445
  aztecNode: this.stateMachine.node,
432
446
  recipientTaggingStore: this.recipientTaggingStore,
433
447
  senderAddressBookStore: this.senderAddressBookStore,
434
- capsuleStore: this.capsuleStore,
448
+ capsuleService: new CapsuleService(this.capsuleStore, await this.keyStore.getAccounts()),
435
449
  privateEventStore: this.privateEventStore,
450
+ messageContextService: this.stateMachine.messageContextService,
451
+ contractSyncService: this.contractSyncService,
452
+ l2TipsStore: this.stateMachine.node,
436
453
  jobId: this.currentJobId,
437
- scopes: 'ALL_SCOPES',
454
+ scopes: await this.keyStore.getAccounts(),
438
455
  });
439
456
 
440
457
  this.state = { name: 'UTILITY' };
@@ -448,8 +465,8 @@ export class TXESession implements TXESessionStateHandler {
448
465
 
449
466
  // Note that while all public and private contexts do is build a single block that we then process when exiting
450
467
  // those, the top level context performs a large number of actions not captured in the following 'close' call. Among
451
- // others, it will create empty blocks (via `txeAdvanceBlocksBy` and `deploy`), create blocks with transactions via
452
- // `txePrivateCallNewFlow` and `txePublicCallNewFlow`, add accounts to PXE via `txeAddAccount`, etc. This is a
468
+ // others, it will create empty blocks (via `advanceBlocksBy` and `deploy`), create blocks with transactions via
469
+ // `privateCallNewFlow` and `publicCallNewFlow`, add accounts to PXE via `addAccount`, etc. This is a
453
470
  // slight inconsistency in the working model of this class, but is not too bad.
454
471
  // TODO: it's quite unfortunate that we need to capture the authwits created to later pass them again when the top
455
472
  // level context is re-created. This is because authwits create a temporary utility context that'd otherwise reset
@@ -503,7 +520,7 @@ export class TXESession implements TXESessionStateHandler {
503
520
  }
504
521
 
505
522
  private utilityExecutorForContractSync(anchorBlock: any) {
506
- return async (call: FunctionCall, scopes: AccessScopes) => {
523
+ return async (call: FunctionCall, scopes: AztecAddress[]) => {
507
524
  const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
508
525
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
509
526
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
@@ -522,8 +539,11 @@ export class TXESession implements TXESessionStateHandler {
522
539
  aztecNode: this.stateMachine.node,
523
540
  recipientTaggingStore: this.recipientTaggingStore,
524
541
  senderAddressBookStore: this.senderAddressBookStore,
525
- capsuleStore: this.capsuleStore,
542
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
526
543
  privateEventStore: this.privateEventStore,
544
+ messageContextService: this.stateMachine.messageContextService,
545
+ contractSyncService: this.contractSyncService,
546
+ l2TipsStore: this.stateMachine.node,
527
547
  jobId: this.currentJobId,
528
548
  scopes,
529
549
  });
@@ -3,6 +3,7 @@ import type { EthAddress } from '@aztec/foundation/eth-address';
3
3
  import { hexToBuffer } from '@aztec/foundation/string';
4
4
  import { type ContractArtifact, ContractArtifactSchema } from '@aztec/stdlib/abi';
5
5
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
6
+ import { BlockHash } from '@aztec/stdlib/block';
6
7
  import { type ContractInstanceWithAddress, ContractInstanceWithAddressSchema } from '@aztec/stdlib/contract';
7
8
 
8
9
  import { z } from 'zod';
@@ -25,6 +26,10 @@ export function addressFromSingle(obj: ForeignCallSingle) {
25
26
  return new AztecAddress(fromSingle(obj));
26
27
  }
27
28
 
29
+ export function blockHashFromSingle(obj: ForeignCallSingle) {
30
+ return new BlockHash(fromSingle(obj));
31
+ }
32
+
28
33
  export function fromArray(obj: ForeignCallArray) {
29
34
  return obj.map(str => Fr.fromBuffer(hexToBuffer(str)));
30
35
  }
@@ -1,19 +1,11 @@
1
1
  import { BlockNumber } from '@aztec/foundation/branded-types';
2
2
  import { Fr } from '@aztec/foundation/curves/bn254';
3
3
  import type { ContractStore } from '@aztec/pxe/server';
4
- import { type ContractArtifact, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
4
+ import { type ContractArtifact, FunctionSelector } from '@aztec/stdlib/abi';
5
5
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
6
- import {
7
- type ContractClassPublic,
8
- type ContractDataSource,
9
- type ContractInstanceWithAddress,
10
- computePrivateFunctionsRoot,
11
- computePublicBytecodeCommitment,
12
- getContractClassPrivateFunctionFromArtifact,
13
- } from '@aztec/stdlib/contract';
6
+ import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
14
7
 
15
8
  export class TXEPublicContractDataSource implements ContractDataSource {
16
- #privateFunctionsRoot: Map<string, Buffer> = new Map();
17
9
  constructor(
18
10
  private blockNumber: BlockNumber,
19
11
  private contractStore: ContractStore,
@@ -24,42 +16,22 @@ export class TXEPublicContractDataSource implements ContractDataSource {
24
16
  }
25
17
 
26
18
  async getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
27
- const contractClass = await this.contractStore.getContractClass(id);
19
+ const contractClass = await this.contractStore.getContractClassWithPreimage(id);
28
20
  if (!contractClass) {
29
21
  return;
30
22
  }
31
- const artifact = await this.contractStore.getContractArtifact(id);
32
- if (!artifact) {
33
- return;
34
- }
35
-
36
- let privateFunctionsRoot;
37
- if (!this.#privateFunctionsRoot.has(id.toString())) {
38
- const privateFunctions = await Promise.all(
39
- artifact.functions
40
- .filter(fn => fn.functionType === FunctionType.PRIVATE)
41
- .map(fn => getContractClassPrivateFunctionFromArtifact(fn)),
42
- );
43
- privateFunctionsRoot = await computePrivateFunctionsRoot(privateFunctions);
44
- this.#privateFunctionsRoot.set(id.toString(), privateFunctionsRoot.toBuffer());
45
- } else {
46
- privateFunctionsRoot = Fr.fromBuffer(this.#privateFunctionsRoot.get(id.toString())!);
47
- }
48
-
49
23
  return {
50
- id,
51
- artifactHash: contractClass!.artifactHash,
52
- packedBytecode: contractClass!.packedBytecode,
53
- privateFunctionsRoot,
54
- version: contractClass!.version,
55
- privateFunctions: [],
56
- utilityFunctions: [],
24
+ id: contractClass.id,
25
+ artifactHash: contractClass.artifactHash,
26
+ packedBytecode: contractClass.packedBytecode,
27
+ privateFunctionsRoot: contractClass.privateFunctionsRoot,
28
+ version: contractClass.version,
57
29
  };
58
30
  }
59
31
 
60
32
  async getBytecodeCommitment(id: Fr): Promise<Fr | undefined> {
61
- const contractClass = await this.contractStore.getContractClass(id);
62
- return contractClass && computePublicBytecodeCommitment(contractClass.packedBytecode);
33
+ const contractClass = await this.contractStore.getContractClassWithPreimage(id);
34
+ return contractClass?.publicBytecodeCommitment;
63
35
  }
64
36
 
65
37
  async getContract(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
@@ -1,12 +0,0 @@
1
- import type { ContractArtifact } from '@aztec/aztec.js/abi';
2
- import { Fr } from '@aztec/aztec.js/fields';
3
- import { ContractStore } from '@aztec/pxe/server';
4
- export type ContractArtifactWithHash = ContractArtifact & {
5
- artifactHash: Fr;
6
- };
7
- export declare class TXEContractStore extends ContractStore {
8
- #private;
9
- addContractArtifact(id: Fr, artifact: ContractArtifact | ContractArtifactWithHash): Promise<void>;
10
- getContractArtifact(contractClassId: Fr): Promise<ContractArtifact | ContractArtifactWithHash | undefined>;
11
- }
12
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhlX2NvbnRyYWN0X3N0b3JlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbC90eGVfY29udHJhY3Rfc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDNUMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRWxELE1BQU0sTUFBTSx3QkFBd0IsR0FBRyxnQkFBZ0IsR0FBRztJQUFFLFlBQVksRUFBRSxFQUFFLENBQUE7Q0FBRSxDQUFDO0FBTy9FLHFCQUFhLGdCQUFpQixTQUFRLGFBQWE7O0lBRzNCLG1CQUFtQixDQUN2QyxFQUFFLEVBQUUsRUFBRSxFQUNOLFFBQVEsRUFBRSxnQkFBZ0IsR0FBRyx3QkFBd0IsR0FDcEQsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUtmO0lBRXFCLG1CQUFtQixDQUN2QyxlQUFlLEVBQUUsRUFBRSxHQUNsQixPQUFPLENBQUMsZ0JBQWdCLEdBQUcsd0JBQXdCLEdBQUcsU0FBUyxDQUFDLENBUWxFO0NBQ0YifQ==
@@ -1 +0,0 @@
1
- {"version":3,"file":"txe_contract_store.d.ts","sourceRoot":"","sources":["../../src/util/txe_contract_store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,MAAM,wBAAwB,GAAG,gBAAgB,GAAG;IAAE,YAAY,EAAE,EAAE,CAAA;CAAE,CAAC;AAO/E,qBAAa,gBAAiB,SAAQ,aAAa;;IAG3B,mBAAmB,CACvC,EAAE,EAAE,EAAE,EACN,QAAQ,EAAE,gBAAgB,GAAG,wBAAwB,GACpD,OAAO,CAAC,IAAI,CAAC,CAKf;IAEqB,mBAAmB,CACvC,eAAe,EAAE,EAAE,GAClB,OAAO,CAAC,gBAAgB,GAAG,wBAAwB,GAAG,SAAS,CAAC,CAQlE;CACF"}
@@ -1,22 +0,0 @@
1
- import { Fr } from '@aztec/aztec.js/fields';
2
- import { ContractStore } from '@aztec/pxe/server';
3
- /*
4
- * A contract store that stores contract artifacts with their hashes. Since
5
- * TXE typically deploys the same contract again and again for multiple tests, caching
6
- * the *very* expensive artifact hash computation improves testing speed significantly.
7
- */ export class TXEContractStore extends ContractStore {
8
- #artifactHashes = new Map();
9
- async addContractArtifact(id, artifact) {
10
- if ('artifactHash' in artifact) {
11
- this.#artifactHashes.set(id.toString(), artifact.artifactHash.toBuffer());
12
- }
13
- await super.addContractArtifact(id, artifact);
14
- }
15
- async getContractArtifact(contractClassId) {
16
- const artifact = await super.getContractArtifact(contractClassId);
17
- if (artifact && this.#artifactHashes.has(contractClassId.toString())) {
18
- artifact.artifactHash = Fr.fromBuffer(this.#artifactHashes.get(contractClassId.toString()));
19
- }
20
- return artifact;
21
- }
22
- }