@aztec/txe 0.0.1-commit.03f7ef2 → 0.0.1-commit.04d373f

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 (141) hide show
  1. package/dest/ContractClassRegistry-KKNT527R.js +3 -0
  2. package/dest/ContractClassRegistry-KKNT527R.js.map +7 -0
  3. package/dest/ContractInstanceRegistry-GSKBNL3Q.js +3 -0
  4. package/dest/ContractInstanceRegistry-GSKBNL3Q.js.map +7 -0
  5. package/dest/FeeJuice-GUJ5O6GB.js +3 -0
  6. package/dest/FeeJuice-GUJ5O6GB.js.map +7 -0
  7. package/dest/MultiCallEntrypoint-ZQPCKVKL.js +3 -0
  8. package/dest/MultiCallEntrypoint-ZQPCKVKL.js.map +7 -0
  9. package/dest/SchnorrAccount-QIXE5DXA.js +3 -0
  10. package/dest/SchnorrAccount-QIXE5DXA.js.map +7 -0
  11. package/dest/bin/check_txe_oracle_version.d.ts +2 -0
  12. package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
  13. package/dest/bin/check_txe_oracle_version.js +32 -0
  14. package/dest/bin/index.js +3 -30
  15. package/dest/bin/index.js.map +7 -0
  16. package/dest/chunk-BJVAAXNA.js +3 -0
  17. package/dest/chunk-BJVAAXNA.js.map +7 -0
  18. package/dest/chunk-DF6RMOC6.js +304 -0
  19. package/dest/chunk-DF6RMOC6.js.map +7 -0
  20. package/dest/chunk-PPJTNNUG.js +265 -0
  21. package/dest/chunk-PPJTNNUG.js.map +7 -0
  22. package/dest/constants.d.ts +5 -0
  23. package/dest/constants.d.ts.map +1 -0
  24. package/dest/constants.js +7 -0
  25. package/dest/dispatcher_pool.d.ts +67 -0
  26. package/dest/dispatcher_pool.d.ts.map +1 -0
  27. package/dest/dispatcher_pool.js +284 -0
  28. package/dest/index.d.ts +188 -7
  29. package/dest/index.d.ts.map +1 -1
  30. package/dest/index.js +148 -75
  31. package/dest/metafile.json +38147 -0
  32. package/dest/msgpackr_fr_extension.d.ts +2 -0
  33. package/dest/msgpackr_fr_extension.d.ts.map +1 -0
  34. package/dest/msgpackr_fr_extension.js +21 -0
  35. package/dest/oracle/interfaces.d.ts +40 -28
  36. package/dest/oracle/interfaces.d.ts.map +1 -1
  37. package/dest/oracle/txe_oracle_public_context.d.ts +18 -13
  38. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  39. package/dest/oracle/txe_oracle_public_context.js +31 -16
  40. package/dest/oracle/txe_oracle_top_level_context.d.ts +49 -31
  41. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  42. package/dest/oracle/txe_oracle_top_level_context.js +265 -119
  43. package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
  44. package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
  45. package/dest/oracle/txe_private_execution_oracle.js +15 -0
  46. package/dest/rpc_server.d.ts +14 -0
  47. package/dest/rpc_server.d.ts.map +1 -0
  48. package/dest/rpc_server.js +78 -0
  49. package/dest/rpc_translator.d.ts +144 -82
  50. package/dest/rpc_translator.d.ts.map +1 -1
  51. package/dest/rpc_translator.js +599 -238
  52. package/dest/server.bundle.js +3 -0
  53. package/dest/server.bundle.js.map +7 -0
  54. package/dest/state_machine/archiver.d.ts +20 -67
  55. package/dest/state_machine/archiver.d.ts.map +1 -1
  56. package/dest/state_machine/archiver.js +65 -182
  57. package/dest/state_machine/dummy_p2p_client.d.ts +28 -17
  58. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  59. package/dest/state_machine/dummy_p2p_client.js +51 -24
  60. package/dest/state_machine/global_variable_builder.d.ts +9 -4
  61. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  62. package/dest/state_machine/global_variable_builder.js +10 -4
  63. package/dest/state_machine/index.d.ts +11 -7
  64. package/dest/state_machine/index.d.ts.map +1 -1
  65. package/dest/state_machine/index.js +57 -16
  66. package/dest/state_machine/mock_epoch_cache.d.ts +26 -8
  67. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  68. package/dest/state_machine/mock_epoch_cache.js +49 -9
  69. package/dest/state_machine/synchronizer.d.ts +6 -6
  70. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  71. package/dest/state_machine/synchronizer.js +4 -4
  72. package/dest/txe_oracle_version.d.ts +17 -0
  73. package/dest/txe_oracle_version.d.ts.map +1 -0
  74. package/dest/txe_oracle_version.js +14 -0
  75. package/dest/txe_session.d.ts +83 -19
  76. package/dest/txe_session.d.ts.map +1 -1
  77. package/dest/txe_session.js +291 -66
  78. package/dest/utils/block_creation.d.ts +4 -4
  79. package/dest/utils/block_creation.d.ts.map +1 -1
  80. package/dest/utils/block_creation.js +18 -5
  81. package/dest/utils/encoding.d.ts +191 -0
  82. package/dest/utils/encoding.d.ts.map +1 -0
  83. package/dest/{util → utils}/encoding.js +7 -2
  84. package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
  85. package/dest/utils/expected_failure_error.d.ts.map +1 -0
  86. package/dest/utils/tx_effect_creation.d.ts +2 -3
  87. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  88. package/dest/utils/tx_effect_creation.js +3 -6
  89. package/dest/utils/txe_account_store.d.ts +10 -0
  90. package/dest/utils/txe_account_store.d.ts.map +1 -0
  91. package/dest/{util/txe_account_data_provider.js → utils/txe_account_store.js} +1 -1
  92. package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
  93. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
  94. package/dest/utils/txe_public_contract_data_source.js +48 -0
  95. package/dest/worker.bundle.js +3 -0
  96. package/dest/worker.bundle.js.map +7 -0
  97. package/dest/worker.d.ts +2 -0
  98. package/dest/worker.d.ts.map +1 -0
  99. package/dest/worker.js +92 -0
  100. package/package.json +38 -22
  101. package/src/bin/check_txe_oracle_version.ts +37 -0
  102. package/src/bin/index.ts +11 -2
  103. package/src/constants.ts +9 -0
  104. package/src/dispatcher_pool.ts +316 -0
  105. package/src/index.ts +166 -80
  106. package/src/msgpackr_fr_extension.ts +23 -0
  107. package/src/oracle/interfaces.ts +48 -34
  108. package/src/oracle/txe_oracle_public_context.ts +46 -18
  109. package/src/oracle/txe_oracle_top_level_context.ts +322 -169
  110. package/src/oracle/txe_private_execution_oracle.ts +30 -0
  111. package/src/rpc_server.ts +87 -0
  112. package/src/rpc_translator.ts +687 -326
  113. package/src/state_machine/archiver.ts +69 -220
  114. package/src/state_machine/dummy_p2p_client.ts +80 -37
  115. package/src/state_machine/global_variable_builder.ts +19 -4
  116. package/src/state_machine/index.ts +73 -16
  117. package/src/state_machine/mock_epoch_cache.ts +61 -14
  118. package/src/state_machine/synchronizer.ts +6 -6
  119. package/src/txe_oracle_version.ts +17 -0
  120. package/src/txe_session.ts +439 -132
  121. package/src/utils/block_creation.ts +19 -16
  122. package/src/{util → utils}/encoding.ts +8 -2
  123. package/src/utils/tx_effect_creation.ts +3 -11
  124. package/src/{util/txe_account_data_provider.ts → utils/txe_account_store.ts} +1 -1
  125. package/src/utils/txe_public_contract_data_source.ts +58 -0
  126. package/src/worker.ts +98 -0
  127. package/dest/util/encoding.d.ts +0 -720
  128. package/dest/util/encoding.d.ts.map +0 -1
  129. package/dest/util/expected_failure_error.d.ts.map +0 -1
  130. package/dest/util/txe_account_data_provider.d.ts +0 -10
  131. package/dest/util/txe_account_data_provider.d.ts.map +0 -1
  132. package/dest/util/txe_contract_data_provider.d.ts +0 -12
  133. package/dest/util/txe_contract_data_provider.d.ts.map +0 -1
  134. package/dest/util/txe_contract_data_provider.js +0 -22
  135. package/dest/util/txe_public_contract_data_source.d.ts +0 -21
  136. package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
  137. package/dest/util/txe_public_contract_data_source.js +0 -67
  138. package/src/util/txe_contract_data_provider.ts +0 -36
  139. package/src/util/txe_public_contract_data_source.ts +0 -86
  140. /package/dest/{util → utils}/expected_failure_error.js +0 -0
  141. /package/src/{util → utils}/expected_failure_error.ts +0 -0
@@ -1,9 +1,6 @@
1
1
  import {
2
2
  CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS,
3
- DEFAULT_DA_GAS_LIMIT,
4
- DEFAULT_L2_GAS_LIMIT,
5
- DEFAULT_TEARDOWN_DA_GAS_LIMIT,
6
- DEFAULT_TEARDOWN_L2_GAS_LIMIT,
3
+ MAX_PRIVATE_LOGS_PER_TX,
7
4
  NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
8
5
  } from '@aztec/constants';
9
6
  import { BlockNumber } from '@aztec/foundation/branded-types';
@@ -13,13 +10,18 @@ import { LogLevels, type Logger, applyStringFormatting, createLogger } from '@az
13
10
  import { TestDateProvider } from '@aztec/foundation/timer';
14
11
  import type { KeyStore } from '@aztec/key-store';
15
12
  import {
16
- AddressDataProvider,
17
- CapsuleDataProvider,
18
- NoteDataProvider,
19
- ORACLE_VERSION,
20
- PrivateEventDataProvider,
21
- RecipientTaggingDataProvider,
22
- SenderTaggingDataProvider,
13
+ AddressStore,
14
+ CapsuleService,
15
+ CapsuleStore,
16
+ type ContractStore,
17
+ type ExecutionHooks,
18
+ NoteStore,
19
+ ORACLE_VERSION_MAJOR,
20
+ PrivateEventStore,
21
+ RecipientTaggingStore,
22
+ SenderAddressBookStore,
23
+ SenderTaggingStore,
24
+ composeHooks,
23
25
  enrichPublicSimulationError,
24
26
  } from '@aztec/pxe/server';
25
27
  import {
@@ -48,7 +50,7 @@ import {
48
50
  PublicContractsDB,
49
51
  PublicProcessor,
50
52
  } from '@aztec/simulator/server';
51
- import { type ContractArtifact, EventSelector, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
53
+ import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
52
54
  import { AuthWitness } from '@aztec/stdlib/auth-witness';
53
55
  import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
54
56
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -61,6 +63,7 @@ import {
61
63
  PrivateToPublicAccumulatedData,
62
64
  PublicCallRequest,
63
65
  } from '@aztec/stdlib/kernel';
66
+ import { hashPublicKey } from '@aztec/stdlib/keys';
64
67
  import { ChonkProof } from '@aztec/stdlib/proofs';
65
68
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
66
69
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -77,14 +80,13 @@ import {
77
80
  collectNested,
78
81
  } from '@aztec/stdlib/tx';
79
82
  import type { UInt64 } from '@aztec/stdlib/types';
80
- import { ForkCheckpoint } from '@aztec/world-state';
83
+ import { ForkCheckpoint } from '@aztec/world-state/native';
81
84
 
85
+ import { DEFAULT_ADDRESS } from '../constants.js';
82
86
  import type { TXEStateMachine } from '../state_machine/index.js';
83
- import { DEFAULT_ADDRESS } from '../txe_session.js';
84
- import type { TXEAccountDataProvider } from '../util/txe_account_data_provider.js';
85
- import type { TXEContractDataProvider } from '../util/txe_contract_data_provider.js';
86
- import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
87
87
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
88
+ import type { TXEAccountStore } from '../utils/txe_account_store.js';
89
+ import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
88
90
  import type { ITxeExecutionOracle } from './interfaces.js';
89
91
 
90
92
  export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
@@ -95,15 +97,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
95
97
 
96
98
  constructor(
97
99
  private stateMachine: TXEStateMachine,
98
- private contractDataProvider: TXEContractDataProvider,
99
- private noteDataProvider: NoteDataProvider,
100
+ private contractStore: ContractStore,
101
+ private noteStore: NoteStore,
100
102
  private keyStore: KeyStore,
101
- private addressDataProvider: AddressDataProvider,
102
- private accountDataProvider: TXEAccountDataProvider,
103
- private senderTaggingDataProvider: SenderTaggingDataProvider,
104
- private recipientTaggingDataProvider: RecipientTaggingDataProvider,
105
- private capsuleDataProvider: CapsuleDataProvider,
106
- private privateEventDataProvider: PrivateEventDataProvider,
103
+ private addressStore: AddressStore,
104
+ private accountStore: TXEAccountStore,
105
+ private senderTaggingStore: SenderTaggingStore,
106
+ private recipientTaggingStore: RecipientTaggingStore,
107
+ private senderAddressBookStore: SenderAddressBookStore,
108
+ private capsuleStore: CapsuleStore,
109
+ private privateEventStore: PrivateEventStore,
107
110
  private nextBlockTimestamp: bigint,
108
111
  private version: Fr,
109
112
  private chainId: Fr,
@@ -113,48 +116,62 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
113
116
  this.logger.debug('Entering Top Level Context');
114
117
  }
115
118
 
116
- utilityAssertCompatibleOracleVersion(version: number): void {
117
- if (version !== ORACLE_VERSION) {
119
+ private contractOracleVersion: { major: number; minor: number } | undefined;
120
+
121
+ assertCompatibleOracleVersion(major: number, minor: number): void {
122
+ if (major !== ORACLE_VERSION_MAJOR) {
123
+ const hint =
124
+ major > ORACLE_VERSION_MAJOR
125
+ ? 'The contract was compiled with a newer version of Aztec.nr than this aztec cli version supports. Upgrade your aztec cli version to a compatible version.'
126
+ : 'The contract was compiled with an older version of Aztec.nr than this aztec cli version supports. Recompile the contract with a compatible version of Aztec.nr.';
118
127
  throw new Error(
119
- `Incompatible oracle version. TXE is using version '${ORACLE_VERSION}', but got a request for '${version}'.`,
128
+ `Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
120
129
  );
121
130
  }
131
+ this.contractOracleVersion = { major, minor };
132
+ }
133
+
134
+ // Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
135
+ nonOracleFunctionGetContractOracleVersion(): { major: number; minor: number } | undefined {
136
+ return this.contractOracleVersion;
122
137
  }
123
138
 
124
139
  // This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
125
140
  // setup.
126
- utilityGetRandomField(): Fr {
141
+ getRandomField(): Fr {
127
142
  return Fr.random();
128
143
  }
129
144
 
130
145
  // We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
131
- utilityDebugLog(level: number, message: string, fields: Fr[]): void {
146
+ log(level: number, message: string, fields: Fr[]): Promise<void> {
132
147
  if (!LogLevels[level]) {
133
- throw new Error(`Invalid debug log level: ${level}`);
148
+ throw new Error(`Invalid log level: ${level}`);
134
149
  }
135
150
  const levelName = LogLevels[level];
136
151
 
137
152
  this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
153
+ return Promise.resolve();
138
154
  }
139
155
 
140
- txeGetDefaultAddress(): AztecAddress {
156
+ getDefaultAddress(): AztecAddress {
141
157
  return DEFAULT_ADDRESS;
142
158
  }
143
159
 
144
- async txeGetNextBlockNumber(): Promise<BlockNumber> {
160
+ async getNextBlockNumber(): Promise<BlockNumber> {
145
161
  return BlockNumber((await this.getLastBlockNumber()) + 1);
146
162
  }
147
163
 
148
- txeGetNextBlockTimestamp(): Promise<bigint> {
164
+ getNextBlockTimestamp(): Promise<bigint> {
149
165
  return Promise.resolve(this.nextBlockTimestamp);
150
166
  }
151
167
 
152
- async txeGetLastBlockTimestamp() {
153
- return (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.timestamp;
168
+ async getLastBlockTimestamp() {
169
+ return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
154
170
  }
155
171
 
156
- async txeGetLastTxEffects() {
157
- const block = await this.stateMachine.archiver.getL2Block('latest');
172
+ async getLastTxEffects() {
173
+ const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
174
+ const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
158
175
 
159
176
  if (block!.body.txEffects.length != 1) {
160
177
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -163,12 +180,41 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
163
180
 
164
181
  const txEffects = block!.body.txEffects[0];
165
182
 
166
- return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
183
+ const privateLogs = txEffects.privateLogs;
184
+ if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
185
+ throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
186
+ }
187
+
188
+ return {
189
+ txHash: txEffects.txHash,
190
+ noteHashes: txEffects.noteHashes,
191
+ nullifiers: txEffects.nullifiers,
192
+ privateLogs,
193
+ };
194
+ }
195
+
196
+ async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
197
+ if (contractAddress.equals(DEFAULT_ADDRESS)) {
198
+ this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
199
+ return;
200
+ }
201
+
202
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
203
+ await this.stateMachine.contractSyncService.ensureContractSynced(
204
+ contractAddress,
205
+ null,
206
+ async (call, execScopes) => {
207
+ await this.executeUtilityCall(call, execScopes, jobId);
208
+ },
209
+ blockHeader,
210
+ jobId,
211
+ [scope],
212
+ );
167
213
  }
168
214
 
169
- async txeGetPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
215
+ async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
170
216
  return (
171
- await this.privateEventDataProvider.getPrivateEvents(selector, {
217
+ await this.privateEventStore.getPrivateEvents(selector, {
172
218
  contractAddress,
173
219
  scopes: [scope],
174
220
  fromBlock: 0,
@@ -177,7 +223,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
177
223
  ).map(e => e.packedEvent);
178
224
  }
179
225
 
180
- async txeAdvanceBlocksBy(blocks: number) {
226
+ async advanceBlocksBy(blocks: number) {
181
227
  this.logger.debug(`time traveling ${blocks} blocks`);
182
228
 
183
229
  for (let i = 0; i < blocks; i++) {
@@ -185,70 +231,79 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
185
231
  }
186
232
  }
187
233
 
188
- txeAdvanceTimestampBy(duration: UInt64) {
234
+ advanceTimestampBy(duration: UInt64) {
189
235
  this.logger.debug(`time traveling ${duration} seconds`);
190
236
  this.nextBlockTimestamp += duration;
191
237
  }
192
238
 
193
- async txeDeploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
239
+ private deploymentNullifier(address: AztecAddress): Promise<Fr> {
240
+ return siloNullifier(AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
241
+ }
242
+
243
+ async deploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
194
244
  // Emit deployment nullifier
195
245
  await this.mineBlock({
196
- nullifiers: [
197
- await siloNullifier(
198
- AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
199
- instance.address.toField(),
200
- ),
201
- ],
246
+ nullifiers: [await this.deploymentNullifier(instance.address)],
202
247
  });
203
248
 
204
249
  if (!secret.equals(Fr.ZERO)) {
205
- await this.txeAddAccount(artifact, instance, secret);
250
+ await this.addAccount(artifact, instance, secret);
206
251
  } else {
207
- await this.contractDataProvider.addContractInstance(instance);
208
- await this.contractDataProvider.addContractArtifact(instance.currentContractClassId, artifact);
252
+ await this.contractStore.addContractInstance(instance);
253
+ await this.contractStore.addContractArtifact(artifact);
209
254
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
210
255
  }
211
256
  }
212
257
 
213
- async txeAddAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
258
+ /**
259
+ * Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
260
+ */
261
+ async mineDeploymentNullifiers(addresses: AztecAddress[]) {
262
+ await this.mineBlock({
263
+ nullifiers: await Promise.all(addresses.map(address => this.deploymentNullifier(address))),
264
+ });
265
+ }
266
+
267
+ async addAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
214
268
  const partialAddress = await computePartialAddress(instance);
215
269
 
216
270
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
217
- await this.contractDataProvider.addContractInstance(instance);
218
- await this.contractDataProvider.addContractArtifact(instance.currentContractClassId, artifact);
271
+ await this.contractStore.addContractInstance(instance);
272
+ await this.contractStore.addContractArtifact(artifact);
219
273
 
220
274
  const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
221
- await this.accountDataProvider.setAccount(completeAddress.address, completeAddress);
222
- await this.addressDataProvider.addCompleteAddress(completeAddress);
275
+ await this.accountStore.setAccount(completeAddress.address, completeAddress);
276
+ await this.addressStore.addCompleteAddress(completeAddress);
223
277
  this.logger.debug(`Created account ${completeAddress.address}`);
224
278
 
225
279
  return completeAddress;
226
280
  }
227
281
 
228
- async txeCreateAccount(secret: Fr) {
282
+ async createAccount(secret: Fr) {
229
283
  // This is a foot gun !
230
284
  const completeAddress = await this.keyStore.addAccount(secret, secret);
231
- await this.accountDataProvider.setAccount(completeAddress.address, completeAddress);
232
- await this.addressDataProvider.addCompleteAddress(completeAddress);
285
+ await this.accountStore.setAccount(completeAddress.address, completeAddress);
286
+ await this.addressStore.addCompleteAddress(completeAddress);
233
287
  this.logger.debug(`Created account ${completeAddress.address}`);
234
288
 
235
289
  return completeAddress;
236
290
  }
237
291
 
238
- async txeAddAuthWitness(address: AztecAddress, messageHash: Fr) {
239
- const account = await this.accountDataProvider.getAccount(address);
240
- const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
292
+ async addAuthWitness(address: AztecAddress, messageHash: Fr) {
293
+ const account = await this.accountStore.getAccount(address);
294
+ const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
295
+ const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
241
296
 
242
297
  const schnorr = new Schnorr();
243
- const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
298
+ const signature = await schnorr.constructSignature(messageHash, privateKey);
244
299
 
245
- const authWitness = new AuthWitness(messageHash, [...signature.toBuffer()]);
300
+ const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
246
301
 
247
302
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
248
303
  }
249
304
 
250
305
  async mineBlock(options: { nullifiers?: Fr[] } = {}) {
251
- const blockNumber = await this.txeGetNextBlockNumber();
306
+ const blockNumber = await this.getNextBlockNumber();
252
307
 
253
308
  const txEffect = TxEffect.empty();
254
309
  txEffect.nullifiers = [getSingleTxBlockRequestHash(blockNumber), ...(options.nullifiers ?? [])];
@@ -272,19 +327,23 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
272
327
  await this.stateMachine.handleL2Block(block);
273
328
  }
274
329
 
275
- async txePrivateCallNewFlow(
276
- from: AztecAddress,
330
+ async privateCallNewFlow(
331
+ from: AztecAddress | undefined,
277
332
  targetContractAddress: AztecAddress = AztecAddress.zero(),
278
333
  functionSelector: FunctionSelector = FunctionSelector.empty(),
279
334
  args: Fr[],
280
335
  argsHash: Fr = Fr.zero(),
281
336
  isStaticCall: boolean = false,
337
+ additionalScopes: AztecAddress[] = [],
338
+ jobId: string,
339
+ authorizedUtilityCallTargets: AztecAddress[],
340
+ gasSettings: GasSettings,
282
341
  ) {
283
342
  this.logger.verbose(
284
- `Executing external function ${await this.contractDataProvider.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
343
+ `Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
285
344
  );
286
345
 
287
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
346
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
288
347
  if (!artifact) {
289
348
  const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
290
349
  ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
@@ -292,60 +351,80 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
292
351
  throw new Error(message);
293
352
  }
294
353
 
295
- const blockNumber = await this.txeGetNextBlockNumber();
354
+ const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
296
355
 
297
- const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
356
+ // Sync notes before executing private function to discover notes from previous transactions
357
+ const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
358
+ await this.executeUtilityCall(call, execScopes, jobId);
359
+ };
298
360
 
299
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
361
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
362
+ await this.stateMachine.contractSyncService.ensureContractSynced(
363
+ targetContractAddress,
364
+ functionSelector,
365
+ utilityExecutor,
366
+ blockHeader,
367
+ jobId,
368
+ scopes,
369
+ );
300
370
 
301
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
371
+ const blockNumber = await this.getNextBlockNumber();
302
372
 
303
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
373
+ const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
374
+ const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
304
375
 
305
376
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
306
377
 
307
- const blockHeader = await this.stateMachine.anchorBlockDataProvider.getBlockHeader();
308
-
309
378
  const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
310
379
  const noteCache = new ExecutionNoteCache(protocolNullifier);
380
+ // In production, the account contract sets the min revertible counter before calling the app function.
381
+ // Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
382
+ // marking all side effects as revertible.
383
+ const minRevertibleSideEffectCounter = 1;
384
+ await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
311
385
  const taggingIndexCache = new ExecutionTaggingIndexCache();
312
386
 
313
387
  const simulator = new WASMSimulator();
314
388
 
315
- const privateExecutionOracle = new PrivateExecutionOracle(
389
+ const privateExecutionOracle = new PrivateExecutionOracle({
316
390
  argsHash,
317
391
  txContext,
318
392
  callContext,
319
- /** Header of a block whose state is used during private execution (not the block the transaction is included in). */
320
- blockHeader,
321
- /** List of transient auth witnesses to be used during this simulation */
322
- Array.from(this.authwits.values()),
323
- /** List of transient auth witnesses to be used during this simulation */
324
- [],
325
- HashedValuesCache.create([new HashedValues(args, argsHash)]),
393
+ anchorBlockHeader: blockHeader,
394
+ utilityExecutor,
395
+ authWitnesses: Array.from(this.authwits.values()),
396
+ capsules: [],
397
+ executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
326
398
  noteCache,
327
399
  taggingIndexCache,
328
- this.contractDataProvider,
329
- this.noteDataProvider,
330
- this.keyStore,
331
- this.addressDataProvider,
332
- this.stateMachine.node,
333
- this.stateMachine.anchorBlockDataProvider,
334
- this.senderTaggingDataProvider,
335
- this.recipientTaggingDataProvider,
336
- this.capsuleDataProvider,
337
- this.privateEventDataProvider,
338
- 0,
339
- 1,
340
- undefined, // log
341
- undefined, // scopes
342
- /**
343
- * In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
344
- * contract would perform, including setting senderForTags.
345
- */
346
- from,
400
+ contractStore: this.contractStore,
401
+ noteStore: this.noteStore,
402
+ keyStore: this.keyStore,
403
+ addressStore: this.addressStore,
404
+ aztecNode: this.stateMachine.node,
405
+ senderTaggingStore: this.senderTaggingStore,
406
+ recipientTaggingStore: this.recipientTaggingStore,
407
+ senderAddressBookStore: this.senderAddressBookStore,
408
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
409
+ privateEventStore: this.privateEventStore,
410
+ contractSyncService: this.stateMachine.contractSyncService,
411
+ jobId,
412
+ totalPublicCalldataCount: 0,
413
+ sideEffectCounter: minRevertibleSideEffectCounter,
414
+ scopes,
415
+ // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
416
+ // contract would perform, including setting senderForTags.
417
+ senderForTags: from,
347
418
  simulator,
348
- );
419
+ messageContextService: this.stateMachine.messageContextService,
420
+ l2TipsStore: this.stateMachine.l2TipsProvider,
421
+ hooks: composeHooks({
422
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(
423
+ isStaticCall ? 'private view' : 'private',
424
+ authorizedUtilityCallTargets,
425
+ ),
426
+ }),
427
+ });
349
428
 
350
429
  // Note: This is a slight modification of simulator.run without any of the checks. Maybe we should modify simulator.run with a boolean value to skip checks.
351
430
  let result: PrivateExecutionResult;
@@ -367,24 +446,27 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
367
446
  );
368
447
  const publicFunctionsCalldata = await Promise.all(
369
448
  publicCallRequests.map(async r => {
370
- const calldata = await privateExecutionOracle.privateLoadFromExecutionCache(r.calldataHash);
449
+ const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
371
450
  return new HashedValues(calldata, r.calldataHash);
372
451
  }),
373
452
  );
374
453
 
375
- // TXE's top level context does not track side effect counters, and as such, minRevertibleSideEffectCounter is always 0.
376
- // This has the unfortunate consequence of always producing revertible nullifiers, which means we
377
- // must set the firstNullifierHint to Fr.ZERO so the txRequestHash is always used as nonce generator
378
- result = new PrivateExecutionResult(executionResult, Fr.ZERO, publicFunctionsCalldata);
454
+ noteCache.finish();
455
+ const nonceGenerator = noteCache.getNonceGenerator();
456
+ result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
379
457
  } catch (err) {
380
458
  throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
381
459
  }
382
460
 
383
- // According to the protocol rules, the nonce generator for the note hashes
384
- // can either be the first nullifier in the tx or the hash of the initial tx request
385
- // if there are none.
386
- const nonceGenerator = result.firstNullifier.equals(Fr.ZERO) ? protocolNullifier : result.firstNullifier;
387
- const { publicInputs } = await generateSimulatedProvingResult(result, nonceGenerator, this.contractDataProvider);
461
+ // According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
462
+ // the nonce generator for the note hashes.
463
+ // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
464
+ const { publicInputs } = await generateSimulatedProvingResult(
465
+ result,
466
+ (addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
467
+ this.stateMachine.node,
468
+ minRevertibleSideEffectCounter,
469
+ );
388
470
 
389
471
  const globals = makeGlobalVariables();
390
472
  globals.blockNumber = blockNumber;
@@ -395,7 +477,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
395
477
 
396
478
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
397
479
 
398
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
480
+ const bindings = this.logger.getBindings();
481
+ const contractsDB = new PublicContractsDB(
482
+ new TXEPublicContractDataSource(blockNumber, this.contractStore),
483
+ bindings,
484
+ );
399
485
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
400
486
  const config = PublicSimulatorConfig.from({
401
487
  skipFeeEnforcement: true,
@@ -408,8 +494,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
408
494
  globals,
409
495
  guardedMerkleTrees,
410
496
  contractsDB,
411
- new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
497
+ new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
412
498
  new TestDateProvider(),
499
+ undefined,
500
+ createLogger('simulator:public-processor', bindings),
413
501
  );
414
502
 
415
503
  const tx = await Tx.create({
@@ -434,7 +522,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
434
522
  } else if (!processedTx.revertCode.isOK()) {
435
523
  if (processedTx.revertReason) {
436
524
  try {
437
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
525
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
438
526
  // eslint-disable-next-line no-empty
439
527
  } catch {}
440
528
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -443,11 +531,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
443
531
  }
444
532
  }
445
533
 
534
+ // Walk the nested private-call tree and collect every offchain effect the transaction emitted.
535
+ // PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
536
+ // `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
537
+ // we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
538
+ const offchainEffects = collectNested([executionResult], r => r.offchainEffects.map(e => e.data));
539
+
446
540
  if (isStaticCall) {
447
541
  await checkpoint!.revert();
448
542
 
449
543
  await forkedWorldTrees.close();
450
- return executionResult.returnValues ?? [];
544
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
451
545
  }
452
546
 
453
547
  const txEffect = TxEffect.empty();
@@ -469,30 +563,25 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
469
563
 
470
564
  await forkedWorldTrees.close();
471
565
 
472
- return executionResult.returnValues ?? [];
566
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
473
567
  }
474
568
 
475
- async txePublicCallNewFlow(
476
- from: AztecAddress,
569
+ async publicCallNewFlow(
570
+ from: AztecAddress | undefined,
477
571
  targetContractAddress: AztecAddress,
478
572
  calldata: Fr[],
479
573
  isStaticCall: boolean,
574
+ gasSettings: GasSettings,
480
575
  ) {
481
576
  this.logger.verbose(
482
- `Executing public function ${await this.contractDataProvider.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
577
+ `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
483
578
  );
484
579
 
485
- const blockNumber = await this.txeGetNextBlockNumber();
486
-
487
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
488
-
489
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
490
-
491
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
580
+ const blockNumber = await this.getNextBlockNumber();
492
581
 
493
582
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
494
583
 
495
- const anchorBlockHeader = await this.stateMachine.anchorBlockDataProvider.getBlockHeader();
584
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
496
585
 
497
586
  const calldataHash = await computeCalldataHash(calldata);
498
587
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
@@ -506,7 +595,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
506
595
 
507
596
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
508
597
 
509
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
598
+ const bindings2 = this.logger.getBindings();
599
+ const contractsDB = new PublicContractsDB(
600
+ new TXEPublicContractDataSource(blockNumber, this.contractStore),
601
+ bindings2,
602
+ );
510
603
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
511
604
  const config = PublicSimulatorConfig.from({
512
605
  skipFeeEnforcement: true,
@@ -515,8 +608,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
515
608
  collectStatistics: false,
516
609
  collectCallMetadata: true,
517
610
  });
518
- const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
519
- const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider());
611
+ const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
612
+ const processor = new PublicProcessor(
613
+ globals,
614
+ guardedMerkleTrees,
615
+ contractsDB,
616
+ simulator,
617
+ new TestDateProvider(),
618
+ undefined,
619
+ createLogger('simulator:public-processor', bindings2),
620
+ );
520
621
 
521
622
  // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
522
623
  // kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
@@ -529,7 +630,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
529
630
  // may require producing reverts.
530
631
  const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
531
632
  revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
532
- from,
633
+ from ?? AztecAddress.NULL_MSG_SENDER,
533
634
  targetContractAddress,
534
635
  isStaticCall,
535
636
  calldataHash,
@@ -547,7 +648,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
547
648
  constantData,
548
649
  /*gasUsed=*/ new Gas(0, 0),
549
650
  /*feePayer=*/ AztecAddress.zero(),
550
- /*includeByTimestamp=*/ 0n,
651
+ /*expirationTimestamp=*/ 0n,
551
652
  inputsForPublic,
552
653
  undefined,
553
654
  );
@@ -574,7 +675,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
574
675
  } else if (!processedTx.revertCode.isOK()) {
575
676
  if (processedTx.revertReason) {
576
677
  try {
577
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
678
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
578
679
  // eslint-disable-next-line no-empty
579
680
  } catch {}
580
681
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -615,26 +716,52 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
615
716
  return returnValues ?? [];
616
717
  }
617
718
 
618
- async txeSimulateUtilityFunction(
719
+ async executeUtilityFunction(
619
720
  targetContractAddress: AztecAddress,
620
721
  functionSelector: FunctionSelector,
621
722
  args: Fr[],
723
+ jobId: string,
724
+ authorizedUtilityCallTargets: AztecAddress[],
622
725
  ) {
623
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
726
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
624
727
  if (!artifact) {
625
728
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
626
729
  }
627
730
 
628
- const call = {
731
+ // Sync notes before executing utility function to discover notes from previous transactions
732
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
733
+ await this.stateMachine.contractSyncService.ensureContractSynced(
734
+ targetContractAddress,
735
+ functionSelector,
736
+ async (call, execScopes) => {
737
+ await this.executeUtilityCall(call, execScopes, jobId);
738
+ },
739
+ blockHeader,
740
+ jobId,
741
+ await this.keyStore.getAccounts(),
742
+ );
743
+
744
+ const call = FunctionCall.from({
629
745
  name: artifact.name,
630
- selector: functionSelector,
631
746
  to: targetContractAddress,
632
- };
747
+ selector: functionSelector,
748
+ type: FunctionType.UTILITY,
749
+ hideMsgSender: false,
750
+ isStatic: false,
751
+ args,
752
+ returnTypes: [],
753
+ });
633
754
 
634
- const entryPointArtifact = await this.contractDataProvider.getFunctionArtifactWithDebugMetadata(
635
- call.to,
636
- call.selector,
637
- );
755
+ return this.executeUtilityCall(call, await this.keyStore.getAccounts(), jobId, authorizedUtilityCallTargets);
756
+ }
757
+
758
+ private async executeUtilityCall(
759
+ call: FunctionCall,
760
+ scopes: AztecAddress[],
761
+ jobId: string,
762
+ authorizedUtilityCallTargets: AztecAddress[] = [],
763
+ ): Promise<Fr[]> {
764
+ const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
638
765
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
639
766
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
640
767
  }
@@ -645,25 +772,38 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
645
772
  });
646
773
 
647
774
  try {
648
- const anchorBlockHeader = await this.stateMachine.anchorBlockDataProvider.getBlockHeader();
649
- const oracle = new UtilityExecutionOracle(
650
- call.to,
651
- [],
652
- [],
775
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
776
+ const simulator = new WASMSimulator();
777
+ const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
778
+ await this.executeUtilityCall(syncCall, execScopes, jobId);
779
+ };
780
+ const oracle = new UtilityExecutionOracle({
781
+ contractAddress: call.to,
782
+ authWitnesses: [],
783
+ capsules: [],
653
784
  anchorBlockHeader,
654
- this.contractDataProvider,
655
- this.noteDataProvider,
656
- this.keyStore,
657
- this.addressDataProvider,
658
- this.stateMachine.node,
659
- this.stateMachine.anchorBlockDataProvider,
660
- this.senderTaggingDataProvider,
661
- this.recipientTaggingDataProvider,
662
- this.capsuleDataProvider,
663
- this.privateEventDataProvider,
664
- );
665
- const acirExecutionResult = await new WASMSimulator()
666
- .executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
785
+ contractStore: this.contractStore,
786
+ noteStore: this.noteStore,
787
+ keyStore: this.keyStore,
788
+ addressStore: this.addressStore,
789
+ aztecNode: this.stateMachine.node,
790
+ recipientTaggingStore: this.recipientTaggingStore,
791
+ senderAddressBookStore: this.senderAddressBookStore,
792
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
793
+ privateEventStore: this.privateEventStore,
794
+ messageContextService: this.stateMachine.messageContextService,
795
+ contractSyncService: this.stateMachine.contractSyncService,
796
+ l2TipsStore: this.stateMachine.l2TipsProvider,
797
+ jobId,
798
+ scopes,
799
+ simulator,
800
+ hooks: composeHooks({
801
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
802
+ }),
803
+ utilityExecutor,
804
+ });
805
+ const acirExecutionResult = await simulator
806
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
667
807
  .catch((err: Error) => {
668
808
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
669
809
  throw new ExecutionError(
@@ -677,10 +817,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
677
817
  );
678
818
  });
679
819
 
680
- this.logger.verbose(`Utility simulation for ${call.to}.${call.selector} completed`);
820
+ this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
681
821
  return witnessMapToFields(acirExecutionResult.returnWitness);
682
822
  } catch (err) {
683
- throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility simulation'));
823
+ throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
684
824
  }
685
825
  }
686
826
 
@@ -690,7 +830,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
690
830
  }
691
831
 
692
832
  private async getLastBlockNumber(): Promise<BlockNumber> {
693
- const header = await this.stateMachine.node.getBlockHeader('latest');
694
- return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
833
+ const block = await this.stateMachine.node.getBlock('latest');
834
+ return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
835
+ }
836
+
837
+ private buildAuthorizeUtilityCallHook(
838
+ callerContext: 'private' | 'private view' | 'utility',
839
+ authorizedTargets: AztecAddress[],
840
+ ): ExecutionHooks['authorizeUtilityCall'] | undefined {
841
+ if (authorizedTargets.length === 0) {
842
+ return undefined;
843
+ }
844
+ return req =>
845
+ Promise.resolve({
846
+ authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)),
847
+ });
695
848
  }
696
849
  }