@aztec/txe 0.0.1-commit.c2eed6949 → 0.0.1-commit.c52d6e7

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 (168) hide show
  1. package/dest/AuthRegistry-QVGDDH5X.js +3 -0
  2. package/dest/AuthRegistry-QVGDDH5X.js.map +7 -0
  3. package/dest/ContractClassRegistry-PVNCKGG7.js +3 -0
  4. package/dest/ContractClassRegistry-PVNCKGG7.js.map +7 -0
  5. package/dest/ContractInstanceRegistry-WLOZKTR6.js +3 -0
  6. package/dest/ContractInstanceRegistry-WLOZKTR6.js.map +7 -0
  7. package/dest/FeeJuice-MAQJU53K.js +3 -0
  8. package/dest/FeeJuice-MAQJU53K.js.map +7 -0
  9. package/dest/HandshakeRegistry-GY5CPEPS.js +3 -0
  10. package/dest/HandshakeRegistry-GY5CPEPS.js.map +7 -0
  11. package/dest/MultiCallEntrypoint-QG5H33ZZ.js +3 -0
  12. package/dest/MultiCallEntrypoint-QG5H33ZZ.js.map +7 -0
  13. package/dest/SchnorrAccount-ADD65DYA.js +3 -0
  14. package/dest/SchnorrAccount-ADD65DYA.js.map +7 -0
  15. package/dest/SchnorrInitializerlessAccount-TWGKRUSY.js +3 -0
  16. package/dest/SchnorrInitializerlessAccount-TWGKRUSY.js.map +7 -0
  17. package/dest/bin/check_txe_oracle_version.d.ts +2 -0
  18. package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
  19. package/dest/bin/check_txe_oracle_version.js +22 -0
  20. package/dest/bin/index.js +3 -30
  21. package/dest/bin/index.js.map +7 -0
  22. package/dest/bin/oracle_test_server.d.ts +3 -0
  23. package/dest/bin/oracle_test_server.d.ts.map +1 -0
  24. package/dest/bin/oracle_test_server.js +41 -0
  25. package/dest/chunk-32UHX7YY.js +3 -0
  26. package/dest/chunk-32UHX7YY.js.map +7 -0
  27. package/dest/chunk-RVEPNDEP.js +304 -0
  28. package/dest/chunk-RVEPNDEP.js.map +7 -0
  29. package/dest/chunk-XWIMXLKD.js +258 -0
  30. package/dest/chunk-XWIMXLKD.js.map +7 -0
  31. package/dest/constants.d.ts +5 -1
  32. package/dest/constants.d.ts.map +1 -1
  33. package/dest/constants.js +9 -1
  34. package/dest/dispatcher_pool.d.ts +67 -0
  35. package/dest/dispatcher_pool.d.ts.map +1 -0
  36. package/dest/dispatcher_pool.js +286 -0
  37. package/dest/index.d.ts +51 -7
  38. package/dest/index.d.ts.map +1 -1
  39. package/dest/index.js +72 -190
  40. package/dest/metafile.json +38833 -0
  41. package/dest/msgpackr_fr_extension.d.ts +2 -0
  42. package/dest/msgpackr_fr_extension.d.ts.map +1 -0
  43. package/dest/msgpackr_fr_extension.js +21 -0
  44. package/dest/oracle/interfaces.d.ts +47 -9
  45. package/dest/oracle/interfaces.d.ts.map +1 -1
  46. package/dest/oracle/tagging_secret_strategy.d.ts +12 -0
  47. package/dest/oracle/tagging_secret_strategy.d.ts.map +1 -0
  48. package/dest/oracle/tagging_secret_strategy.js +12 -0
  49. package/dest/oracle/test-resolver/default_fixtures.d.ts +16 -0
  50. package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
  51. package/dest/oracle/test-resolver/default_fixtures.js +200 -0
  52. package/dest/oracle/test-resolver/index.d.ts +9 -0
  53. package/dest/oracle/test-resolver/index.d.ts.map +1 -0
  54. package/dest/oracle/test-resolver/index.js +32 -0
  55. package/dest/oracle/test-resolver/resolver.d.ts +48 -0
  56. package/dest/oracle/test-resolver/resolver.d.ts.map +1 -0
  57. package/dest/oracle/test-resolver/resolver.js +181 -0
  58. package/dest/oracle/txe_oracle_public_context.d.ts +26 -2
  59. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  60. package/dest/oracle/txe_oracle_public_context.js +49 -1
  61. package/dest/oracle/txe_oracle_registry.d.ts +172 -0
  62. package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
  63. package/dest/oracle/txe_oracle_registry.js +767 -0
  64. package/dest/oracle/txe_oracle_top_level_context.d.ts +58 -18
  65. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  66. package/dest/oracle/txe_oracle_top_level_context.js +558 -304
  67. package/dest/oracle/txe_oracle_version.d.ts +17 -0
  68. package/dest/oracle/txe_oracle_version.d.ts.map +1 -0
  69. package/dest/oracle/txe_oracle_version.js +14 -0
  70. package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
  71. package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
  72. package/dest/oracle/txe_private_execution_oracle.js +15 -0
  73. package/dest/rpc_server.d.ts +14 -0
  74. package/dest/rpc_server.d.ts.map +1 -0
  75. package/dest/rpc_server.js +78 -0
  76. package/dest/rpc_translator.d.ts +116 -233
  77. package/dest/rpc_translator.d.ts.map +1 -1
  78. package/dest/rpc_translator.js +799 -636
  79. package/dest/server.bundle.js +3 -0
  80. package/dest/server.bundle.js.map +7 -0
  81. package/dest/state_machine/archiver.d.ts +4 -3
  82. package/dest/state_machine/archiver.d.ts.map +1 -1
  83. package/dest/state_machine/archiver.js +24 -14
  84. package/dest/state_machine/dummy_p2p_client.d.ts +16 -7
  85. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  86. package/dest/state_machine/dummy_p2p_client.js +25 -4
  87. package/dest/state_machine/global_variable_builder.d.ts +10 -6
  88. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  89. package/dest/state_machine/global_variable_builder.js +8 -5
  90. package/dest/state_machine/index.d.ts +11 -7
  91. package/dest/state_machine/index.d.ts.map +1 -1
  92. package/dest/state_machine/index.js +50 -14
  93. package/dest/state_machine/mock_epoch_cache.d.ts +2 -2
  94. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  95. package/dest/state_machine/mock_epoch_cache.js +3 -3
  96. package/dest/state_machine/synchronizer.d.ts +10 -2
  97. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  98. package/dest/state_machine/synchronizer.js +19 -6
  99. package/dest/txe_session.d.ts +92 -20
  100. package/dest/txe_session.d.ts.map +1 -1
  101. package/dest/txe_session.js +324 -69
  102. package/dest/utils/block_creation.d.ts +2 -2
  103. package/dest/utils/block_creation.d.ts.map +1 -1
  104. package/dest/utils/block_creation.js +2 -2
  105. package/dest/utils/encoding.d.ts +194 -0
  106. package/dest/utils/encoding.d.ts.map +1 -0
  107. package/dest/{util → utils}/encoding.js +7 -2
  108. package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
  109. package/dest/utils/expected_failure_error.d.ts.map +1 -0
  110. package/dest/utils/tx_effect_creation.d.ts +1 -1
  111. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  112. package/dest/utils/tx_effect_creation.js +0 -1
  113. package/dest/{util → utils}/txe_account_store.d.ts +1 -1
  114. package/dest/utils/txe_account_store.d.ts.map +1 -0
  115. package/dest/utils/txe_artifact_resolver.d.ts +37 -0
  116. package/dest/utils/txe_artifact_resolver.d.ts.map +1 -0
  117. package/dest/utils/txe_artifact_resolver.js +161 -0
  118. package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
  119. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
  120. package/dest/{util → utils}/txe_public_contract_data_source.js +7 -4
  121. package/dest/worker.bundle.js +3 -0
  122. package/dest/worker.bundle.js.map +7 -0
  123. package/dest/worker.d.ts +2 -0
  124. package/dest/worker.d.ts.map +1 -0
  125. package/dest/worker.js +92 -0
  126. package/package.json +38 -21
  127. package/src/bin/check_txe_oracle_version.ts +31 -0
  128. package/src/bin/index.ts +11 -2
  129. package/src/bin/oracle_test_server.ts +51 -0
  130. package/src/constants.ts +11 -1
  131. package/src/dispatcher_pool.ts +317 -0
  132. package/src/index.ts +99 -227
  133. package/src/msgpackr_fr_extension.ts +23 -0
  134. package/src/oracle/interfaces.ts +47 -8
  135. package/src/oracle/tagging_secret_strategy.ts +25 -0
  136. package/src/oracle/test-resolver/default_fixtures.ts +271 -0
  137. package/src/oracle/test-resolver/index.ts +44 -0
  138. package/src/oracle/test-resolver/resolver.ts +245 -0
  139. package/src/oracle/txe_oracle_public_context.ts +62 -0
  140. package/src/oracle/txe_oracle_registry.ts +556 -0
  141. package/src/oracle/txe_oracle_top_level_context.ts +364 -117
  142. package/src/oracle/txe_oracle_version.ts +17 -0
  143. package/src/oracle/txe_private_execution_oracle.ts +30 -0
  144. package/src/rpc_server.ts +87 -0
  145. package/src/rpc_translator.ts +889 -901
  146. package/src/state_machine/archiver.ts +37 -16
  147. package/src/state_machine/dummy_p2p_client.ts +44 -11
  148. package/src/state_machine/global_variable_builder.ts +12 -11
  149. package/src/state_machine/index.ts +62 -32
  150. package/src/state_machine/mock_epoch_cache.ts +4 -4
  151. package/src/state_machine/synchronizer.ts +27 -6
  152. package/src/txe_session.ts +561 -85
  153. package/src/utils/block_creation.ts +2 -1
  154. package/src/{util → utils}/encoding.ts +8 -2
  155. package/src/utils/tx_effect_creation.ts +0 -2
  156. package/src/utils/txe_artifact_resolver.ts +217 -0
  157. package/src/{util → utils}/txe_public_contract_data_source.ts +6 -4
  158. package/src/worker.ts +98 -0
  159. package/dest/util/encoding.d.ts +0 -788
  160. package/dest/util/encoding.d.ts.map +0 -1
  161. package/dest/util/expected_failure_error.d.ts.map +0 -1
  162. package/dest/util/txe_account_store.d.ts.map +0 -1
  163. package/dest/util/txe_public_contract_data_source.d.ts +0 -20
  164. package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
  165. /package/dest/{util → utils}/expected_failure_error.js +0 -0
  166. /package/dest/{util → utils}/txe_account_store.js +0 -0
  167. /package/src/{util → utils}/expected_failure_error.ts +0 -0
  168. /package/src/{util → utils}/txe_account_store.ts +0 -0
@@ -1,39 +1,45 @@
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';
10
7
  import { Schnorr } from '@aztec/foundation/crypto/schnorr';
11
8
  import { Fr } from '@aztec/foundation/curves/bn254';
9
+ import type { EthAddress } from '@aztec/foundation/eth-address';
12
10
  import { LogLevels, type Logger, applyStringFormatting, createLogger } from '@aztec/foundation/log';
13
11
  import { TestDateProvider } from '@aztec/foundation/timer';
14
12
  import type { KeyStore } from '@aztec/key-store';
15
- import type { AccessScopes } from '@aztec/pxe/client/lazy';
16
13
  import {
17
14
  AddressStore,
15
+ AnchoredContractData,
16
+ CapsuleService,
18
17
  CapsuleStore,
19
18
  type ContractStore,
20
- type ContractSyncService,
19
+ type ExecutionHooks,
20
+ FactService,
21
+ FactStore,
21
22
  NoteStore,
22
- ORACLE_VERSION,
23
+ ORACLE_VERSION_MAJOR,
23
24
  PrivateEventStore,
24
25
  RecipientTaggingStore,
25
- SenderAddressBookStore,
26
26
  SenderTaggingStore,
27
+ TaggingSecretSourcesStore,
28
+ type TaggingSecretStrategy,
29
+ composeHooks,
27
30
  enrichPublicSimulationError,
28
31
  } from '@aztec/pxe/server';
29
32
  import {
33
+ CONTRACT_INSTANCE,
30
34
  ExecutionNoteCache,
31
35
  ExecutionTaggingIndexCache,
32
36
  HashedValuesCache,
33
37
  type IMiscOracle,
34
- Oracle,
38
+ type Option,
35
39
  PrivateExecutionOracle,
40
+ TransientArrayService,
36
41
  UtilityExecutionOracle,
42
+ buildACIRCallback,
37
43
  executePrivateFunction,
38
44
  generateSimulatedProvingResult,
39
45
  } from '@aztec/pxe/simulator';
@@ -47,10 +53,10 @@ import {
47
53
  witnessMapToFields,
48
54
  } from '@aztec/simulator/client';
49
55
  import {
50
- CppPublicTxSimulator,
51
56
  GuardedMerkleTreeOperations,
52
57
  PublicContractsDB,
53
58
  PublicProcessor,
59
+ PublicTxSimulator,
54
60
  } from '@aztec/simulator/server';
55
61
  import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
56
62
  import { AuthWitness } from '@aztec/stdlib/auth-witness';
@@ -65,6 +71,10 @@ import {
65
71
  PrivateToPublicAccumulatedData,
66
72
  PublicCallRequest,
67
73
  } from '@aztec/stdlib/kernel';
74
+ import { deriveKeys, hashPublicKey } from '@aztec/stdlib/keys';
75
+ import type { PrivateLog } from '@aztec/stdlib/logs';
76
+ import { AppTaggingSecretKind } from '@aztec/stdlib/logs';
77
+ import { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
68
78
  import { ChonkProof } from '@aztec/stdlib/proofs';
69
79
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
70
80
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -81,14 +91,16 @@ import {
81
91
  collectNested,
82
92
  } from '@aztec/stdlib/tx';
83
93
  import type { UInt64 } from '@aztec/stdlib/types';
84
- import { ForkCheckpoint } from '@aztec/world-state';
94
+ import { ForkCheckpoint } from '@aztec/world-state/native';
85
95
 
86
- import { DEFAULT_ADDRESS } from '../constants.js';
96
+ import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
87
97
  import type { TXEStateMachine } from '../state_machine/index.js';
88
- import type { TXEAccountStore } from '../util/txe_account_store.js';
89
- import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
90
98
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
99
+ import type { TXEAccountStore } from '../utils/txe_account_store.js';
100
+ import type { TXEArtifactResolver } from '../utils/txe_artifact_resolver.js';
101
+ import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
91
102
  import type { ITxeExecutionOracle } from './interfaces.js';
103
+ import { type TXETaggingSecretStrategies, makeResolveTaggingSecretStrategyHook } from './tagging_secret_strategy.js';
92
104
 
93
105
  export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
94
106
  isMisc = true as const;
@@ -105,25 +117,42 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
105
117
  private accountStore: TXEAccountStore,
106
118
  private senderTaggingStore: SenderTaggingStore,
107
119
  private recipientTaggingStore: RecipientTaggingStore,
108
- private senderAddressBookStore: SenderAddressBookStore,
120
+ private taggingSecretSourcesStore: TaggingSecretSourcesStore,
109
121
  private capsuleStore: CapsuleStore,
122
+ private factStore: FactStore,
110
123
  private privateEventStore: PrivateEventStore,
111
124
  private nextBlockTimestamp: bigint,
112
125
  private version: Fr,
113
126
  private chainId: Fr,
114
127
  private authwits: Map<string, AuthWitness>,
115
- private readonly contractSyncService: ContractSyncService,
128
+ private taggingSecretStrategies: TXETaggingSecretStrategies,
129
+ private authorizeAllUtilityCallTargets: boolean,
130
+ private readonly artifactResolver: TXEArtifactResolver,
131
+ private readonly rootPath: string,
132
+ private readonly packageName: string,
116
133
  ) {
117
134
  this.logger = createLogger('txe:top_level_context');
118
135
  this.logger.debug('Entering Top Level Context');
119
136
  }
120
137
 
121
- assertCompatibleOracleVersion(version: number): void {
122
- if (version !== ORACLE_VERSION) {
138
+ private contractOracleVersion: { major: number; minor: number } | undefined;
139
+
140
+ assertCompatibleOracleVersion(major: number, minor: number): void {
141
+ if (major !== ORACLE_VERSION_MAJOR) {
142
+ const hint =
143
+ major > ORACLE_VERSION_MAJOR
144
+ ? '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.'
145
+ : '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.';
123
146
  throw new Error(
124
- `Incompatible oracle version. TXE is using version '${ORACLE_VERSION}', but got a request for '${version}'.`,
147
+ `Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
125
148
  );
126
149
  }
150
+ this.contractOracleVersion = { major, minor };
151
+ }
152
+
153
+ // Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
154
+ nonOracleFunctionGetContractOracleVersion(): { major: number; minor: number } | undefined {
155
+ return this.contractOracleVersion;
127
156
  }
128
157
 
129
158
  // This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
@@ -133,7 +162,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
133
162
  }
134
163
 
135
164
  // We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
136
- log(level: number, message: string, fields: Fr[]): Promise<void> {
165
+ log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
137
166
  if (!LogLevels[level]) {
138
167
  throw new Error(`Invalid log level: ${level}`);
139
168
  }
@@ -156,12 +185,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
156
185
  }
157
186
 
158
187
  async getLastBlockTimestamp() {
159
- return (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.timestamp;
188
+ return (await this.stateMachine.node.getBlockData('latest'))!.header.globalVariables.timestamp;
160
189
  }
161
190
 
162
- async getLastTxEffects() {
191
+ async getLastTxEffects(): Promise<{ txHash: TxHash; noteHashes: Fr[]; nullifiers: Fr[]; privateLogs: PrivateLog[] }> {
163
192
  const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
164
- const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
193
+ const block = await this.stateMachine.archiver.getBlock({ number: latestBlockNumber });
165
194
 
166
195
  if (block!.body.txEffects.length != 1) {
167
196
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -170,7 +199,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
170
199
 
171
200
  const txEffects = block!.body.txEffects[0];
172
201
 
173
- return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
202
+ const privateLogs = txEffects.privateLogs;
203
+ if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
204
+ throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
205
+ }
206
+
207
+ return {
208
+ txHash: txEffects.txHash,
209
+ noteHashes: txEffects.noteHashes,
210
+ nullifiers: txEffects.nullifiers,
211
+ privateLogs,
212
+ };
174
213
  }
175
214
 
176
215
  async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
@@ -184,7 +223,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
184
223
  contractAddress,
185
224
  null,
186
225
  async (call, execScopes) => {
187
- await this.executeUtilityCall(call, execScopes, jobId);
226
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
188
227
  },
189
228
  blockHeader,
190
229
  jobId,
@@ -193,7 +232,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
193
232
  }
194
233
 
195
234
  async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
196
- return (
235
+ const events = (
197
236
  await this.privateEventStore.getPrivateEvents(selector, {
198
237
  contractAddress,
199
238
  scopes: [scope],
@@ -201,6 +240,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
201
240
  toBlock: (await this.getLastBlockNumber()) + 1,
202
241
  })
203
242
  ).map(e => e.packedEvent);
243
+
244
+ if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
245
+ throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
246
+ }
247
+ if (events.some(e => e.length > MAX_PRIVATE_EVENT_LEN)) {
248
+ throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
249
+ }
250
+
251
+ return events;
204
252
  }
205
253
 
206
254
  async advanceBlocksBy(blocks: number) {
@@ -216,34 +264,71 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
216
264
  this.nextBlockTimestamp += duration;
217
265
  }
218
266
 
219
- async deploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
267
+ private deploymentNullifier(address: AztecAddress): Promise<Fr> {
268
+ return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
269
+ }
270
+
271
+ async deploy(
272
+ contractPath: string,
273
+ initializer: string,
274
+ args: Fr[],
275
+ secret: Fr,
276
+ salt: Fr,
277
+ deployer: AztecAddress,
278
+ ): Promise<Fr[]> {
279
+ const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
280
+ rootPath: this.rootPath,
281
+ packageName: this.packageName,
282
+ contractPath,
283
+ initializer,
284
+ args,
285
+ secret,
286
+ salt,
287
+ deployer,
288
+ });
289
+
220
290
  // Emit deployment nullifier
221
291
  await this.mineBlock({
222
- nullifiers: [
223
- await siloNullifier(
224
- AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
225
- instance.address.toField(),
226
- ),
227
- ],
292
+ nullifiers: [await this.deploymentNullifier(instance.address)],
228
293
  });
229
294
 
230
295
  if (!secret.equals(Fr.ZERO)) {
231
- await this.addAccount(artifact, instance, secret);
296
+ await this.registerContractAndAddAccount(artifact, instance, secret);
232
297
  } else {
233
298
  await this.contractStore.addContractInstance(instance);
234
299
  await this.contractStore.addContractArtifact(artifact);
235
300
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
236
301
  }
302
+
303
+ return CONTRACT_INSTANCE.serialization!.fn(instance).flat();
304
+ }
305
+
306
+ /**
307
+ * Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
308
+ */
309
+ async mineDeploymentNullifiers(addresses: AztecAddress[]) {
310
+ await this.mineBlock({
311
+ nullifiers: await Promise.all(addresses.map(address => this.deploymentNullifier(address))),
312
+ });
313
+ }
314
+
315
+ async addAccount(secret: Fr) {
316
+ const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
317
+ return this.registerContractAndAddAccount(artifact, instance, secret);
237
318
  }
238
319
 
239
- async addAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
320
+ private async registerContractAndAddAccount(
321
+ artifact: ContractArtifact,
322
+ instance: ContractInstanceWithAddress,
323
+ secret: Fr,
324
+ ) {
240
325
  const partialAddress = await computePartialAddress(instance);
241
326
 
242
327
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
243
328
  await this.contractStore.addContractInstance(instance);
244
329
  await this.contractStore.addContractArtifact(artifact);
245
330
 
246
- const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
331
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
247
332
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
248
333
  await this.addressStore.addCompleteAddress(completeAddress);
249
334
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -251,9 +336,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
251
336
  return completeAddress;
252
337
  }
253
338
 
254
- async createAccount(secret: Fr) {
255
- // This is a foot gun !
256
- const completeAddress = await this.keyStore.addAccount(secret, secret);
339
+ async createAccount(secret: Fr, partialAddress: Fr) {
340
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
257
341
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
258
342
  await this.addressStore.addCompleteAddress(completeAddress);
259
343
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -263,17 +347,57 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
263
347
 
264
348
  async addAuthWitness(address: AztecAddress, messageHash: Fr) {
265
349
  const account = await this.accountStore.getAccount(address);
266
- const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
350
+ const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
351
+ const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
267
352
 
268
353
  const schnorr = new Schnorr();
269
- const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
354
+ const signature = await schnorr.constructSignature(messageHash, privateKey);
270
355
 
271
- const authWitness = new AuthWitness(messageHash, [...signature.toBuffer()]);
356
+ const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
272
357
 
273
358
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
274
359
  }
275
360
 
276
- async mineBlock(options: { nullifiers?: Fr[] } = {}) {
361
+ setTaggingSecretStrategies(
362
+ unconstrainedStrategy: Option<TaggingSecretStrategy>,
363
+ constrainedStrategy: Option<TaggingSecretStrategy>,
364
+ ): void {
365
+ const apply = (mode: AppTaggingSecretKind, strategy: Option<TaggingSecretStrategy>) => {
366
+ if (strategy.isSome()) {
367
+ this.taggingSecretStrategies.set(mode, strategy.value);
368
+ } else {
369
+ this.taggingSecretStrategies.delete(mode);
370
+ }
371
+ };
372
+ apply(AppTaggingSecretKind.UNCONSTRAINED, unconstrainedStrategy);
373
+ apply(AppTaggingSecretKind.CONSTRAINED, constrainedStrategy);
374
+ }
375
+
376
+ setAuthorizeAllUtilityCallTargets(authorizeAll: boolean): void {
377
+ this.authorizeAllUtilityCallTargets = authorizeAll;
378
+ }
379
+
380
+ async sendL1ToL2Message(content: Fr, secretHash: Fr, sender: EthAddress, recipient: AztecAddress): Promise<Fr> {
381
+ // Messages are appended to the tree, so the next free slot is simply the current tree size.
382
+ const { size } = await this.stateMachine.synchronizer
383
+ .getCommitted()
384
+ .getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
385
+ const leafIndex = new Fr(size);
386
+
387
+ const message = new L1ToL2Message(
388
+ new L1Actor(sender, this.chainId.toNumber()),
389
+ new L2Actor(recipient, this.version.toNumber()),
390
+ content,
391
+ secretHash,
392
+ leafIndex,
393
+ );
394
+
395
+ await this.mineBlock({ l1ToL2Messages: [message.hash()] });
396
+
397
+ return leafIndex;
398
+ }
399
+
400
+ async mineBlock(options: { nullifiers?: Fr[]; l1ToL2Messages?: Fr[] } = {}) {
277
401
  const blockNumber = await this.getNextBlockNumber();
278
402
 
279
403
  const txEffect = TxEffect.empty();
@@ -281,7 +405,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
281
405
  txEffect.txHash = new TxHash(new Fr(blockNumber));
282
406
 
283
407
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
284
- await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
408
+ await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
285
409
 
286
410
  const globals = makeGlobalVariables(undefined, {
287
411
  blockNumber,
@@ -295,23 +419,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
295
419
 
296
420
  this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
297
421
 
298
- await this.stateMachine.handleL2Block(block);
422
+ await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
299
423
  }
300
424
 
301
425
  async privateCallNewFlow(
302
- from: AztecAddress,
426
+ from: AztecAddress | undefined,
303
427
  targetContractAddress: AztecAddress = AztecAddress.zero(),
304
428
  functionSelector: FunctionSelector = FunctionSelector.empty(),
305
429
  args: Fr[],
306
430
  argsHash: Fr = Fr.zero(),
307
431
  isStaticCall: boolean = false,
432
+ additionalScopes: AztecAddress[] = [],
308
433
  jobId: string,
434
+ authorizedUtilityCallTargets: AztecAddress[],
435
+ gasSettings: GasSettings,
309
436
  ) {
437
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
438
+ const anchoredContractData = new AnchoredContractData(
439
+ this.contractStore,
440
+ this.stateMachine.contractClassService,
441
+ blockHeader,
442
+ );
443
+
310
444
  this.logger.verbose(
311
- `Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
445
+ `Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
312
446
  );
313
447
 
314
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
448
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
315
449
  if (!artifact) {
316
450
  const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
317
451
  ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
@@ -319,32 +453,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
319
453
  throw new Error(message);
320
454
  }
321
455
 
322
- // When `from` is the zero address (e.g. when deploying a new account contract), we return an
323
- // empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
324
- const effectiveScopes = from.isZero() ? [] : [from];
456
+ const scopes = from === undefined ? additionalScopes : [from, ...additionalScopes];
325
457
 
326
458
  // Sync notes before executing private function to discover notes from previous transactions
327
- const utilityExecutor = async (call: FunctionCall, execScopes: AccessScopes) => {
328
- await this.executeUtilityCall(call, execScopes, jobId);
459
+ const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
460
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
329
461
  };
330
462
 
331
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
332
463
  await this.stateMachine.contractSyncService.ensureContractSynced(
333
464
  targetContractAddress,
334
465
  functionSelector,
335
466
  utilityExecutor,
336
467
  blockHeader,
337
468
  jobId,
338
- effectiveScopes,
469
+ scopes,
339
470
  );
340
471
 
341
472
  const blockNumber = await this.getNextBlockNumber();
342
473
 
343
- const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
344
-
345
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
346
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
347
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
474
+ const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
475
+ const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
348
476
 
349
477
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
350
478
 
@@ -359,9 +487,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
359
487
 
360
488
  const simulator = new WASMSimulator();
361
489
 
490
+ const transientArrayService = new TransientArrayService();
362
491
  const privateExecutionOracle = new PrivateExecutionOracle({
363
492
  argsHash,
364
493
  txContext,
494
+ txRequestSalt: Fr.ZERO,
365
495
  callContext,
366
496
  anchorBlockHeader: blockHeader,
367
497
  utilityExecutor,
@@ -370,26 +500,36 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
370
500
  executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
371
501
  noteCache,
372
502
  taggingIndexCache,
373
- contractStore: this.contractStore,
503
+ anchoredContractData,
374
504
  noteStore: this.noteStore,
375
505
  keyStore: this.keyStore,
376
506
  addressStore: this.addressStore,
377
507
  aztecNode: this.stateMachine.node,
378
508
  senderTaggingStore: this.senderTaggingStore,
379
509
  recipientTaggingStore: this.recipientTaggingStore,
380
- senderAddressBookStore: this.senderAddressBookStore,
381
- capsuleStore: this.capsuleStore,
510
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
511
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
512
+ factService: new FactService(this.factStore, scopes),
382
513
  privateEventStore: this.privateEventStore,
383
514
  contractSyncService: this.stateMachine.contractSyncService,
384
515
  jobId,
385
516
  totalPublicCalldataCount: 0,
386
517
  sideEffectCounter: minRevertibleSideEffectCounter,
387
- scopes: effectiveScopes,
518
+ scopes,
388
519
  // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
389
520
  // contract would perform, including setting senderForTags.
390
521
  senderForTags: from,
391
522
  simulator,
392
- messageContextService: this.stateMachine.messageContextService,
523
+ txResolver: this.stateMachine.txResolver,
524
+ l2TipsStore: this.stateMachine.l2TipsProvider,
525
+ hooks: composeHooks({
526
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(
527
+ isStaticCall ? 'private view' : 'private',
528
+ authorizedUtilityCallTargets,
529
+ ),
530
+ resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies),
531
+ }),
532
+ transientArrayService,
393
533
  });
394
534
 
395
535
  // 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.
@@ -412,12 +552,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
412
552
  );
413
553
  const publicFunctionsCalldata = await Promise.all(
414
554
  publicCallRequests.map(async r => {
415
- const calldata = await privateExecutionOracle.loadFromExecutionCache(r.calldataHash);
555
+ const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
416
556
  return new HashedValues(calldata, r.calldataHash);
417
557
  }),
418
558
  );
419
559
 
420
- noteCache.finish();
421
560
  const nonceGenerator = noteCache.getNonceGenerator();
422
561
  result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
423
562
  } catch (err) {
@@ -429,7 +568,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
429
568
  // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
430
569
  const { publicInputs } = await generateSimulatedProvingResult(
431
570
  result,
432
- (addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
571
+ (addr, sel) => anchoredContractData.getDebugFunctionName(addr, sel),
433
572
  this.stateMachine.node,
434
573
  minRevertibleSideEffectCounter,
435
574
  );
@@ -441,7 +580,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
441
580
  globals.version = this.version;
442
581
  globals.gasFees = GasFees.empty();
443
582
 
444
- const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
583
+ await using forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
445
584
 
446
585
  const bindings = this.logger.getBindings();
447
586
  const contractsDB = new PublicContractsDB(
@@ -456,11 +595,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
456
595
  collectStatistics: false,
457
596
  collectCallMetadata: true,
458
597
  });
598
+ // The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
599
+ const forkId = forkedWorldTrees.getRevision().forkId;
459
600
  const processor = new PublicProcessor(
460
601
  globals,
461
602
  guardedMerkleTrees,
462
603
  contractsDB,
463
- new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
604
+ new PublicTxSimulator(
605
+ this.stateMachine.synchronizer.avmSimulator,
606
+ globals,
607
+ contractsDB,
608
+ forkId,
609
+ config,
610
+ bindings,
611
+ ),
464
612
  new TestDateProvider(),
465
613
  undefined,
466
614
  createLogger('simulator:public-processor', bindings),
@@ -488,7 +636,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
488
636
  } else if (!processedTx.revertCode.isOK()) {
489
637
  if (processedTx.revertReason) {
490
638
  try {
491
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
639
+ await enrichPublicSimulationError(
640
+ processedTx.revertReason,
641
+ this.contractStore,
642
+ this.stateMachine.contractClassService,
643
+ await this.stateMachine.anchorBlockStore.getBlockHeader(),
644
+ this.logger,
645
+ );
492
646
  // eslint-disable-next-line no-empty
493
647
  } catch {}
494
648
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -497,11 +651,15 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
497
651
  }
498
652
  }
499
653
 
654
+ // Walk the nested private-call tree and collect every offchain effect the transaction emitted.
655
+ // PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
656
+ // `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
657
+ // we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
658
+ const offchainEffects = collectNested([executionResult], r => r.offchainEffects.map(e => e.data));
659
+
500
660
  if (isStaticCall) {
501
661
  await checkpoint!.revert();
502
-
503
- await forkedWorldTrees.close();
504
- return executionResult.returnValues ?? [];
662
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
505
663
  }
506
664
 
507
665
  const txEffect = TxEffect.empty();
@@ -521,33 +679,31 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
521
679
 
522
680
  await this.stateMachine.handleL2Block(l2Block);
523
681
 
524
- await forkedWorldTrees.close();
525
-
526
- return executionResult.returnValues ?? [];
682
+ return { returnValues: executionResult.returnValues ?? [], offchainEffects };
527
683
  }
528
684
 
529
685
  async publicCallNewFlow(
530
- from: AztecAddress,
686
+ from: AztecAddress | undefined,
531
687
  targetContractAddress: AztecAddress,
532
688
  calldata: Fr[],
533
689
  isStaticCall: boolean,
690
+ gasSettings: GasSettings,
534
691
  ) {
692
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
693
+ const anchoredContractData = new AnchoredContractData(
694
+ this.contractStore,
695
+ this.stateMachine.contractClassService,
696
+ anchorBlockHeader,
697
+ );
698
+
535
699
  this.logger.verbose(
536
- `Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
700
+ `Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
537
701
  );
538
702
 
539
703
  const blockNumber = await this.getNextBlockNumber();
540
704
 
541
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
542
-
543
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
544
-
545
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
546
-
547
705
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
548
706
 
549
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
550
-
551
707
  const calldataHash = await computeCalldataHash(calldata);
552
708
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
553
709
 
@@ -558,7 +714,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
558
714
  globals.version = this.version;
559
715
  globals.gasFees = GasFees.empty();
560
716
 
561
- const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
717
+ await using forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
562
718
 
563
719
  const bindings2 = this.logger.getBindings();
564
720
  const contractsDB = new PublicContractsDB(
@@ -573,7 +729,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
573
729
  collectStatistics: false,
574
730
  collectCallMetadata: true,
575
731
  });
576
- const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
732
+ // The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
733
+ const forkId2 = forkedWorldTrees.getRevision().forkId;
734
+ const simulator = new PublicTxSimulator(
735
+ this.stateMachine.synchronizer.avmSimulator,
736
+ globals,
737
+ contractsDB,
738
+ forkId2,
739
+ config,
740
+ bindings2,
741
+ );
577
742
  const processor = new PublicProcessor(
578
743
  globals,
579
744
  guardedMerkleTrees,
@@ -595,7 +760,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
595
760
  // may require producing reverts.
596
761
  const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
597
762
  revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(
598
- from,
763
+ from ?? AztecAddress.NULL_MSG_SENDER,
599
764
  targetContractAddress,
600
765
  isStaticCall,
601
766
  calldataHash,
@@ -640,7 +805,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
640
805
  } else if (!processedTx.revertCode.isOK()) {
641
806
  if (processedTx.revertReason) {
642
807
  try {
643
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
808
+ await enrichPublicSimulationError(
809
+ processedTx.revertReason,
810
+ this.contractStore,
811
+ this.stateMachine.contractClassService,
812
+ anchorBlockHeader,
813
+ this.logger,
814
+ );
644
815
  // eslint-disable-next-line no-empty
645
816
  } catch {}
646
817
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -653,9 +824,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
653
824
 
654
825
  if (isStaticCall) {
655
826
  await checkpoint!.revert();
656
-
657
- await forkedWorldTrees.close();
658
-
659
827
  return returnValues ?? [];
660
828
  }
661
829
 
@@ -676,33 +844,39 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
676
844
 
677
845
  await this.stateMachine.handleL2Block(l2Block);
678
846
 
679
- await forkedWorldTrees.close();
680
-
681
847
  return returnValues ?? [];
682
848
  }
683
849
 
684
850
  async executeUtilityFunction(
851
+ from: AztecAddress | undefined,
685
852
  targetContractAddress: AztecAddress,
686
853
  functionSelector: FunctionSelector,
687
854
  args: Fr[],
688
855
  jobId: string,
856
+ authorizedUtilityCallTargets: AztecAddress[],
689
857
  ) {
690
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
858
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
859
+ const anchoredContractData = new AnchoredContractData(
860
+ this.contractStore,
861
+ this.stateMachine.contractClassService,
862
+ blockHeader,
863
+ );
864
+
865
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
691
866
  if (!artifact) {
692
867
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
693
868
  }
694
869
 
695
870
  // Sync notes before executing utility function to discover notes from previous transactions
696
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
697
871
  await this.stateMachine.contractSyncService.ensureContractSynced(
698
872
  targetContractAddress,
699
873
  functionSelector,
700
874
  async (call, execScopes) => {
701
- await this.executeUtilityCall(call, execScopes, jobId);
875
+ await this.executeUtilityCall(call, { scopes: execScopes, jobId });
702
876
  },
703
877
  blockHeader,
704
878
  jobId,
705
- 'ALL_SCOPES',
879
+ await this.keyStore.getAccounts(),
706
880
  );
707
881
 
708
882
  const call = FunctionCall.from({
@@ -713,14 +887,36 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
713
887
  hideMsgSender: false,
714
888
  isStatic: false,
715
889
  args,
716
- returnTypes: [],
717
890
  });
718
891
 
719
- return this.executeUtilityCall(call, 'ALL_SCOPES', jobId);
892
+ return this.executeUtilityCall(call, {
893
+ from,
894
+ scopes: await this.keyStore.getAccounts(),
895
+ jobId,
896
+ authorizedUtilityCallTargets,
897
+ });
720
898
  }
721
899
 
722
- private async executeUtilityCall(call: FunctionCall, scopes: AccessScopes, jobId: string): Promise<Fr[]> {
723
- const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
900
+ private async executeUtilityCall(
901
+ call: FunctionCall,
902
+ {
903
+ from = AztecAddress.NULL_MSG_SENDER,
904
+ scopes,
905
+ jobId,
906
+ authorizedUtilityCallTargets = [],
907
+ }: { from?: AztecAddress; scopes: AztecAddress[]; jobId: string; authorizedUtilityCallTargets?: AztecAddress[] },
908
+ ): Promise<Fr[]> {
909
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
910
+ const anchoredContractData = new AnchoredContractData(
911
+ this.contractStore,
912
+ this.stateMachine.contractClassService,
913
+ anchorBlockHeader,
914
+ );
915
+
916
+ const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
917
+ if (!entryPointArtifact) {
918
+ throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
919
+ }
724
920
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
725
921
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
726
922
  }
@@ -731,28 +927,45 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
731
927
  });
732
928
 
733
929
  try {
734
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
930
+ const simulator = new WASMSimulator();
931
+ const utilityExecutor = async (syncCall: FunctionCall, execScopes: AztecAddress[]) => {
932
+ await this.executeUtilityCall(syncCall, { scopes: execScopes, jobId });
933
+ };
735
934
  const oracle = new UtilityExecutionOracle({
736
- contractAddress: call.to,
935
+ callContext: CallContext.from({
936
+ msgSender: from,
937
+ contractAddress: call.to,
938
+ functionSelector: call.selector,
939
+ isStaticCall: true,
940
+ }),
737
941
  authWitnesses: [],
738
942
  capsules: [],
739
943
  anchorBlockHeader,
740
- contractStore: this.contractStore,
944
+ anchoredContractData,
741
945
  noteStore: this.noteStore,
742
946
  keyStore: this.keyStore,
743
947
  addressStore: this.addressStore,
744
948
  aztecNode: this.stateMachine.node,
745
949
  recipientTaggingStore: this.recipientTaggingStore,
746
- senderAddressBookStore: this.senderAddressBookStore,
747
- capsuleStore: this.capsuleStore,
950
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
951
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
952
+ factService: new FactService(this.factStore, scopes),
748
953
  privateEventStore: this.privateEventStore,
749
- messageContextService: this.stateMachine.messageContextService,
750
- contractSyncService: this.contractSyncService,
954
+ txResolver: this.stateMachine.txResolver,
955
+ contractSyncService: this.stateMachine.contractSyncService,
956
+ l2TipsStore: this.stateMachine.l2TipsProvider,
751
957
  jobId,
752
958
  scopes,
959
+ simulator,
960
+ hooks: composeHooks({
961
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets),
962
+ }),
963
+ utilityExecutor,
964
+ // Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
965
+ transientArrayService: new TransientArrayService(),
753
966
  });
754
- const acirExecutionResult = await new WASMSimulator()
755
- .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
967
+ const acirExecutionResult = await simulator
968
+ .executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle))
756
969
  .catch((err: Error) => {
757
970
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
758
971
  throw new ExecutionError(
@@ -773,13 +986,47 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
773
986
  }
774
987
  }
775
988
 
776
- close(): [bigint, Map<string, AuthWitness>] {
989
+ close(): {
990
+ nextBlockTimestamp: bigint;
991
+ authwits: Map<string, AuthWitness>;
992
+ taggingSecretStrategies: TXETaggingSecretStrategies;
993
+ authorizeAllUtilityCallTargets: boolean;
994
+ } {
777
995
  this.logger.debug('Exiting Top Level Context');
778
- return [this.nextBlockTimestamp, this.authwits];
996
+ return {
997
+ nextBlockTimestamp: this.nextBlockTimestamp,
998
+ authwits: this.authwits,
999
+ taggingSecretStrategies: this.taggingSecretStrategies,
1000
+ authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets,
1001
+ };
779
1002
  }
780
1003
 
781
1004
  private async getLastBlockNumber(): Promise<BlockNumber> {
782
- const header = await this.stateMachine.node.getBlockHeader('latest');
783
- return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
1005
+ const block = await this.stateMachine.node.getBlock('latest');
1006
+ return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
1007
+ }
1008
+
1009
+ private buildAuthorizeUtilityCallHook(
1010
+ callerContext: 'private' | 'private view' | 'utility',
1011
+ authorizedTargets: AztecAddress[],
1012
+ ): ExecutionHooks['authorizeUtilityCall'] | undefined {
1013
+ if (this.authorizeAllUtilityCallTargets) {
1014
+ return authorizeAllUtilityCallsHook;
1015
+ }
1016
+ if (authorizedTargets.length === 0) {
1017
+ return undefined;
1018
+ }
1019
+ return req =>
1020
+ Promise.resolve({
1021
+ authorized: req.callerContext === callerContext && authorizedTargets.some(t => t.equals(req.target)),
1022
+ });
784
1023
  }
785
1024
  }
1025
+
1026
+ /**
1027
+ * An `authorizeUtilityCall` hook that authorizes every cross-contract utility call.
1028
+ *
1029
+ * Backs the `aztec_txe_setAuthorizeAllUtilityCallTargets` oracle.
1030
+ */
1031
+ export const authorizeAllUtilityCallsHook: NonNullable<ExecutionHooks['authorizeUtilityCall']> = () =>
1032
+ Promise.resolve({ authorized: true });