@aztec/txe 0.0.1-commit.f504929 → 0.0.1-commit.f5a9928

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 (170) hide show
  1. package/dest/AuthRegistry-56AMRLSQ.js +3 -0
  2. package/dest/AuthRegistry-56AMRLSQ.js.map +7 -0
  3. package/dest/ContractClassRegistry-CRN27URB.js +3 -0
  4. package/dest/ContractClassRegistry-CRN27URB.js.map +7 -0
  5. package/dest/ContractInstanceRegistry-GRGL26IC.js +3 -0
  6. package/dest/ContractInstanceRegistry-GRGL26IC.js.map +7 -0
  7. package/dest/FeeJuice-J23RVHLW.js +3 -0
  8. package/dest/FeeJuice-J23RVHLW.js.map +7 -0
  9. package/dest/HandshakeRegistry-5.0.1-PEFCLEGP.js +3 -0
  10. package/dest/HandshakeRegistry-5.0.1-PEFCLEGP.js.map +7 -0
  11. package/dest/HandshakeRegistry-GNFACTEE.js +3 -0
  12. package/dest/HandshakeRegistry-GNFACTEE.js.map +7 -0
  13. package/dest/MultiCallEntrypoint-MIDICLQB.js +3 -0
  14. package/dest/MultiCallEntrypoint-MIDICLQB.js.map +7 -0
  15. package/dest/SchnorrAccount-ZRENHSMV.js +3 -0
  16. package/dest/SchnorrAccount-ZRENHSMV.js.map +7 -0
  17. package/dest/SchnorrInitializerlessAccount-L56LOFSV.js +3 -0
  18. package/dest/SchnorrInitializerlessAccount-L56LOFSV.js.map +7 -0
  19. package/dest/bin/check_txe_oracle_version.d.ts +2 -0
  20. package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
  21. package/dest/bin/check_txe_oracle_version.js +53 -0
  22. package/dest/bin/index.js +3 -30
  23. package/dest/bin/index.js.map +7 -0
  24. package/dest/bin/oracle_test_server.d.ts +3 -0
  25. package/dest/bin/oracle_test_server.d.ts.map +1 -0
  26. package/dest/bin/oracle_test_server.js +41 -0
  27. package/dest/chunk-BJVAAXNA.js +3 -0
  28. package/dest/chunk-BJVAAXNA.js.map +7 -0
  29. package/dest/chunk-C2WBKKGS.js +266 -0
  30. package/dest/chunk-C2WBKKGS.js.map +7 -0
  31. package/dest/chunk-OFS2CI6U.js +304 -0
  32. package/dest/chunk-OFS2CI6U.js.map +7 -0
  33. package/dest/constants.d.ts +5 -1
  34. package/dest/constants.d.ts.map +1 -1
  35. package/dest/constants.js +9 -1
  36. package/dest/dispatcher_pool.d.ts +67 -0
  37. package/dest/dispatcher_pool.d.ts.map +1 -0
  38. package/dest/dispatcher_pool.js +286 -0
  39. package/dest/index.d.ts +51 -7
  40. package/dest/index.d.ts.map +1 -1
  41. package/dest/index.js +72 -190
  42. package/dest/metafile.json +40416 -0
  43. package/dest/msgpackr_fr_extension.d.ts +2 -0
  44. package/dest/msgpackr_fr_extension.d.ts.map +1 -0
  45. package/dest/msgpackr_fr_extension.js +21 -0
  46. package/dest/oracle/interfaces.d.ts +47 -9
  47. package/dest/oracle/interfaces.d.ts.map +1 -1
  48. package/dest/oracle/tagging_secret_strategy.d.ts +12 -0
  49. package/dest/oracle/tagging_secret_strategy.d.ts.map +1 -0
  50. package/dest/oracle/tagging_secret_strategy.js +12 -0
  51. package/dest/oracle/test-resolver/default_fixtures.d.ts +16 -0
  52. package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
  53. package/dest/oracle/test-resolver/default_fixtures.js +200 -0
  54. package/dest/oracle/test-resolver/index.d.ts +9 -0
  55. package/dest/oracle/test-resolver/index.d.ts.map +1 -0
  56. package/dest/oracle/test-resolver/index.js +32 -0
  57. package/dest/oracle/test-resolver/resolver.d.ts +48 -0
  58. package/dest/oracle/test-resolver/resolver.d.ts.map +1 -0
  59. package/dest/oracle/test-resolver/resolver.js +181 -0
  60. package/dest/oracle/txe_oracle_public_context.d.ts +26 -2
  61. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  62. package/dest/oracle/txe_oracle_public_context.js +49 -1
  63. package/dest/oracle/txe_oracle_registry.d.ts +172 -0
  64. package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
  65. package/dest/oracle/txe_oracle_registry.js +767 -0
  66. package/dest/oracle/txe_oracle_top_level_context.d.ts +58 -17
  67. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  68. package/dest/oracle/txe_oracle_top_level_context.js +259 -88
  69. package/dest/oracle/txe_oracle_version.d.ts +17 -0
  70. package/dest/oracle/txe_oracle_version.d.ts.map +1 -0
  71. package/dest/oracle/txe_oracle_version.js +14 -0
  72. package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
  73. package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
  74. package/dest/oracle/txe_private_execution_oracle.js +15 -0
  75. package/dest/rpc_server.d.ts +14 -0
  76. package/dest/rpc_server.d.ts.map +1 -0
  77. package/dest/rpc_server.js +78 -0
  78. package/dest/rpc_translator.d.ts +115 -228
  79. package/dest/rpc_translator.d.ts.map +1 -1
  80. package/dest/rpc_translator.js +791 -607
  81. package/dest/server.bundle.js +3 -0
  82. package/dest/server.bundle.js.map +7 -0
  83. package/dest/state_machine/archiver.d.ts +6 -5
  84. package/dest/state_machine/archiver.d.ts.map +1 -1
  85. package/dest/state_machine/archiver.js +28 -20
  86. package/dest/state_machine/dummy_p2p_client.d.ts +18 -8
  87. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  88. package/dest/state_machine/dummy_p2p_client.js +31 -4
  89. package/dest/state_machine/global_variable_builder.d.ts +10 -6
  90. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  91. package/dest/state_machine/global_variable_builder.js +8 -5
  92. package/dest/state_machine/index.d.ts +11 -5
  93. package/dest/state_machine/index.d.ts.map +1 -1
  94. package/dest/state_machine/index.js +50 -10
  95. package/dest/state_machine/mock_epoch_cache.d.ts +16 -3
  96. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  97. package/dest/state_machine/mock_epoch_cache.js +29 -2
  98. package/dest/state_machine/synchronizer.d.ts +9 -6
  99. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  100. package/dest/state_machine/synchronizer.js +10 -6
  101. package/dest/txe_session.d.ts +90 -19
  102. package/dest/txe_session.d.ts.map +1 -1
  103. package/dest/txe_session.js +315 -61
  104. package/dest/utils/block_creation.d.ts +2 -2
  105. package/dest/utils/block_creation.d.ts.map +1 -1
  106. package/dest/utils/block_creation.js +2 -2
  107. package/dest/utils/encoding.d.ts +192 -0
  108. package/dest/utils/encoding.d.ts.map +1 -0
  109. package/dest/{util → utils}/encoding.js +7 -2
  110. package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
  111. package/dest/utils/expected_failure_error.d.ts.map +1 -0
  112. package/dest/utils/tx_effect_creation.d.ts +1 -1
  113. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  114. package/dest/utils/tx_effect_creation.js +0 -1
  115. package/dest/{util → utils}/txe_account_store.d.ts +1 -1
  116. package/dest/utils/txe_account_store.d.ts.map +1 -0
  117. package/dest/utils/txe_artifact_resolver.d.ts +37 -0
  118. package/dest/utils/txe_artifact_resolver.d.ts.map +1 -0
  119. package/dest/utils/txe_artifact_resolver.js +161 -0
  120. package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
  121. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
  122. package/dest/{util → utils}/txe_public_contract_data_source.js +8 -7
  123. package/dest/worker.bundle.js +3 -0
  124. package/dest/worker.bundle.js.map +7 -0
  125. package/dest/worker.d.ts +2 -0
  126. package/dest/worker.d.ts.map +1 -0
  127. package/dest/worker.js +92 -0
  128. package/package.json +38 -21
  129. package/src/bin/check_txe_oracle_version.ts +67 -0
  130. package/src/bin/index.ts +11 -2
  131. package/src/bin/oracle_test_server.ts +51 -0
  132. package/src/constants.ts +11 -1
  133. package/src/dispatcher_pool.ts +317 -0
  134. package/src/index.ts +99 -227
  135. package/src/msgpackr_fr_extension.ts +23 -0
  136. package/src/oracle/interfaces.ts +47 -8
  137. package/src/oracle/tagging_secret_strategy.ts +25 -0
  138. package/src/oracle/test-resolver/default_fixtures.ts +271 -0
  139. package/src/oracle/test-resolver/index.ts +44 -0
  140. package/src/oracle/test-resolver/resolver.ts +245 -0
  141. package/src/oracle/txe_oracle_public_context.ts +62 -0
  142. package/src/oracle/txe_oracle_registry.ts +556 -0
  143. package/src/oracle/txe_oracle_top_level_context.ts +342 -97
  144. package/src/oracle/txe_oracle_version.ts +17 -0
  145. package/src/oracle/txe_private_execution_oracle.ts +30 -0
  146. package/src/rpc_server.ts +87 -0
  147. package/src/rpc_translator.ts +882 -870
  148. package/src/state_machine/archiver.ts +41 -20
  149. package/src/state_machine/dummy_p2p_client.ts +49 -12
  150. package/src/state_machine/global_variable_builder.ts +12 -11
  151. package/src/state_machine/index.ts +63 -28
  152. package/src/state_machine/mock_epoch_cache.ts +38 -3
  153. package/src/state_machine/synchronizer.ts +13 -7
  154. package/src/txe_session.ts +552 -75
  155. package/src/utils/block_creation.ts +2 -1
  156. package/src/{util → utils}/encoding.ts +8 -2
  157. package/src/utils/tx_effect_creation.ts +0 -2
  158. package/src/utils/txe_artifact_resolver.ts +217 -0
  159. package/src/{util → utils}/txe_public_contract_data_source.ts +6 -6
  160. package/src/worker.ts +98 -0
  161. package/dest/util/encoding.d.ts +0 -720
  162. package/dest/util/encoding.d.ts.map +0 -1
  163. package/dest/util/expected_failure_error.d.ts.map +0 -1
  164. package/dest/util/txe_account_store.d.ts.map +0 -1
  165. package/dest/util/txe_public_contract_data_source.d.ts +0 -20
  166. package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
  167. /package/dest/{util → utils}/expected_failure_error.js +0 -0
  168. /package/dest/{util → utils}/txe_account_store.js +0 -0
  169. /package/src/{util → utils}/expected_failure_error.ts +0 -0
  170. /package/src/{util → utils}/txe_account_store.ts +0 -0
@@ -1,11 +1,11 @@
1
- import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT, DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
1
+ import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, MAX_PRIVATE_LOGS_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
2
2
  import { BlockNumber } from '@aztec/foundation/branded-types';
3
3
  import { Schnorr } from '@aztec/foundation/crypto/schnorr';
4
4
  import { Fr } from '@aztec/foundation/curves/bn254';
5
5
  import { LogLevels, applyStringFormatting, createLogger } from '@aztec/foundation/log';
6
6
  import { TestDateProvider } from '@aztec/foundation/timer';
7
- import { ORACLE_VERSION, enrichPublicSimulationError } from '@aztec/pxe/server';
8
- import { ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache, Oracle, PrivateExecutionOracle, UtilityExecutionOracle, executePrivateFunction, generateSimulatedProvingResult } from '@aztec/pxe/simulator';
7
+ import { AnchoredContractData, CapsuleService, FactService, ORACLE_VERSION_MAJOR, composeHooks, enrichPublicSimulationError } from '@aztec/pxe/server';
8
+ import { CONTRACT_INSTANCE, ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache, PrivateExecutionOracle, TransientArrayService, UtilityExecutionOracle, buildACIRCallback, executePrivateFunction, generateSimulatedProvingResult } from '@aztec/pxe/simulator';
9
9
  import { ExecutionError, WASMSimulator, createSimulationError, extractCallStack, resolveAssertionMessageFromError, toACVMWitness, witnessMapToFields } from '@aztec/simulator/client';
10
10
  import { CppPublicTxSimulator, GuardedMerkleTreeOperations, PublicContractsDB, PublicProcessor } from '@aztec/simulator/server';
11
11
  import { FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
@@ -13,17 +13,21 @@ import { AuthWitness } from '@aztec/stdlib/auth-witness';
13
13
  import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
14
14
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
15
15
  import { computePartialAddress } from '@aztec/stdlib/contract';
16
- import { Gas, GasFees, GasSettings } from '@aztec/stdlib/gas';
16
+ import { Gas, GasFees } from '@aztec/stdlib/gas';
17
17
  import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
18
18
  import { PartialPrivateTailPublicInputsForPublic, PrivateKernelTailCircuitPublicInputs, PrivateToPublicAccumulatedData, PublicCallRequest } from '@aztec/stdlib/kernel';
19
+ import { deriveKeys, hashPublicKey } from '@aztec/stdlib/keys';
20
+ import { AppTaggingSecretKind } from '@aztec/stdlib/logs';
21
+ import { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
19
22
  import { ChonkProof } from '@aztec/stdlib/proofs';
20
23
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
21
24
  import { MerkleTreeId } from '@aztec/stdlib/trees';
22
25
  import { CallContext, HashedValues, PrivateExecutionResult, Tx, TxConstantData, TxContext, TxEffect, TxHash, collectNested } from '@aztec/stdlib/tx';
23
- import { ForkCheckpoint } from '@aztec/world-state';
24
- import { DEFAULT_ADDRESS } from '../constants.js';
25
- import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
26
+ import { ForkCheckpoint } from '@aztec/world-state/native';
27
+ import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
26
28
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
29
+ import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
30
+ import { makeResolveTaggingSecretStrategyHook } from './tagging_secret_strategy.js';
27
31
  export class TXEOracleTopLevelContext {
28
32
  stateMachine;
29
33
  contractStore;
@@ -33,17 +37,23 @@ export class TXEOracleTopLevelContext {
33
37
  accountStore;
34
38
  senderTaggingStore;
35
39
  recipientTaggingStore;
36
- senderAddressBookStore;
40
+ taggingSecretSourcesStore;
37
41
  capsuleStore;
42
+ factStore;
38
43
  privateEventStore;
39
44
  nextBlockTimestamp;
40
45
  version;
41
46
  chainId;
42
47
  authwits;
48
+ taggingSecretStrategies;
49
+ authorizeAllUtilityCallTargets;
50
+ artifactResolver;
51
+ rootPath;
52
+ packageName;
43
53
  isMisc;
44
54
  isTxe;
45
55
  logger;
46
- constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits){
56
+ constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, taggingSecretSourcesStore, capsuleStore, factStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits, taggingSecretStrategies, authorizeAllUtilityCallTargets, artifactResolver, rootPath, packageName){
47
57
  this.stateMachine = stateMachine;
48
58
  this.contractStore = contractStore;
49
59
  this.noteStore = noteStore;
@@ -52,22 +62,38 @@ export class TXEOracleTopLevelContext {
52
62
  this.accountStore = accountStore;
53
63
  this.senderTaggingStore = senderTaggingStore;
54
64
  this.recipientTaggingStore = recipientTaggingStore;
55
- this.senderAddressBookStore = senderAddressBookStore;
65
+ this.taggingSecretSourcesStore = taggingSecretSourcesStore;
56
66
  this.capsuleStore = capsuleStore;
67
+ this.factStore = factStore;
57
68
  this.privateEventStore = privateEventStore;
58
69
  this.nextBlockTimestamp = nextBlockTimestamp;
59
70
  this.version = version;
60
71
  this.chainId = chainId;
61
72
  this.authwits = authwits;
73
+ this.taggingSecretStrategies = taggingSecretStrategies;
74
+ this.authorizeAllUtilityCallTargets = authorizeAllUtilityCallTargets;
75
+ this.artifactResolver = artifactResolver;
76
+ this.rootPath = rootPath;
77
+ this.packageName = packageName;
62
78
  this.isMisc = true;
63
79
  this.isTxe = true;
64
80
  this.logger = createLogger('txe:top_level_context');
65
81
  this.logger.debug('Entering Top Level Context');
66
82
  }
67
- assertCompatibleOracleVersion(version) {
68
- if (version !== ORACLE_VERSION) {
69
- throw new Error(`Incompatible oracle version. TXE is using version '${ORACLE_VERSION}', but got a request for '${version}'.`);
83
+ contractOracleVersion;
84
+ assertCompatibleOracleVersion(major, minor) {
85
+ if (major !== ORACLE_VERSION_MAJOR) {
86
+ const hint = major > ORACLE_VERSION_MAJOR ? '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.' : '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.';
87
+ throw new Error(`Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`);
70
88
  }
89
+ this.contractOracleVersion = {
90
+ major,
91
+ minor
92
+ };
93
+ }
94
+ // Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
95
+ nonOracleFunctionGetContractOracleVersion() {
96
+ return this.contractOracleVersion;
71
97
  }
72
98
  // This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
73
99
  // setup.
@@ -75,7 +101,7 @@ export class TXEOracleTopLevelContext {
75
101
  return Fr.random();
76
102
  }
77
103
  // We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
78
- log(level, message, fields) {
104
+ log(level, message, _fieldsSize, fields) {
79
105
  if (!LogLevels[level]) {
80
106
  throw new Error(`Invalid log level: ${level}`);
81
107
  }
@@ -95,20 +121,27 @@ export class TXEOracleTopLevelContext {
95
121
  return Promise.resolve(this.nextBlockTimestamp);
96
122
  }
97
123
  async getLastBlockTimestamp() {
98
- return (await this.stateMachine.node.getBlockHeader('latest')).globalVariables.timestamp;
124
+ return (await this.stateMachine.node.getBlockData('latest')).header.globalVariables.timestamp;
99
125
  }
100
126
  async getLastTxEffects() {
101
127
  const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
102
- const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
128
+ const block = await this.stateMachine.archiver.getBlock({
129
+ number: latestBlockNumber
130
+ });
103
131
  if (block.body.txEffects.length != 1) {
104
132
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
105
133
  throw new Error(`Expected a single transaction in the last block, found ${block.body.txEffects.length}`);
106
134
  }
107
135
  const txEffects = block.body.txEffects[0];
136
+ const privateLogs = txEffects.privateLogs;
137
+ if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
138
+ throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
139
+ }
108
140
  return {
109
141
  txHash: txEffects.txHash,
110
142
  noteHashes: txEffects.noteHashes,
111
- nullifiers: txEffects.nullifiers
143
+ nullifiers: txEffects.nullifiers,
144
+ privateLogs
112
145
  };
113
146
  }
114
147
  async syncContractNonOracleMethod(contractAddress, scope, jobId) {
@@ -118,13 +151,16 @@ export class TXEOracleTopLevelContext {
118
151
  }
119
152
  const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
120
153
  await this.stateMachine.contractSyncService.ensureContractSynced(contractAddress, null, async (call, execScopes)=>{
121
- await this.executeUtilityCall(call, execScopes, jobId);
154
+ await this.executeUtilityCall(call, {
155
+ scopes: execScopes,
156
+ jobId
157
+ });
122
158
  }, blockHeader, jobId, [
123
159
  scope
124
160
  ]);
125
161
  }
126
162
  async getPrivateEvents(selector, contractAddress, scope) {
127
- return (await this.privateEventStore.getPrivateEvents(selector, {
163
+ const events = (await this.privateEventStore.getPrivateEvents(selector, {
128
164
  contractAddress,
129
165
  scopes: [
130
166
  scope
@@ -132,6 +168,13 @@ export class TXEOracleTopLevelContext {
132
168
  fromBlock: 0,
133
169
  toBlock: await this.getLastBlockNumber() + 1
134
170
  })).map((e)=>e.packedEvent);
171
+ if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
172
+ throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
173
+ }
174
+ if (events.some((e)=>e.length > MAX_PRIVATE_EVENT_LEN)) {
175
+ throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
176
+ }
177
+ return events;
135
178
  }
136
179
  async advanceBlocksBy(blocks) {
137
180
  this.logger.debug(`time traveling ${blocks} blocks`);
@@ -143,35 +186,59 @@ export class TXEOracleTopLevelContext {
143
186
  this.logger.debug(`time traveling ${duration} seconds`);
144
187
  this.nextBlockTimestamp += duration;
145
188
  }
146
- async deploy(artifact, instance, secret) {
189
+ deploymentNullifier(address) {
190
+ return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
191
+ }
192
+ async deploy(contractPath, initializer, args, secret, salt, deployer) {
193
+ const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
194
+ rootPath: this.rootPath,
195
+ packageName: this.packageName,
196
+ contractPath,
197
+ initializer,
198
+ args,
199
+ secret,
200
+ salt,
201
+ deployer
202
+ });
147
203
  // Emit deployment nullifier
148
204
  await this.mineBlock({
149
205
  nullifiers: [
150
- await siloNullifier(AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), instance.address.toField())
206
+ await this.deploymentNullifier(instance.address)
151
207
  ]
152
208
  });
153
209
  if (!secret.equals(Fr.ZERO)) {
154
- await this.addAccount(artifact, instance, secret);
210
+ await this.registerContractAndAddAccount(artifact, instance, secret);
155
211
  } else {
156
212
  await this.contractStore.addContractInstance(instance);
157
213
  await this.contractStore.addContractArtifact(artifact);
158
214
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
159
215
  }
216
+ return CONTRACT_INSTANCE.serialization.fn(instance).flat();
217
+ }
218
+ /**
219
+ * Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
220
+ */ async mineDeploymentNullifiers(addresses) {
221
+ await this.mineBlock({
222
+ nullifiers: await Promise.all(addresses.map((address)=>this.deploymentNullifier(address)))
223
+ });
224
+ }
225
+ async addAccount(secret) {
226
+ const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
227
+ return this.registerContractAndAddAccount(artifact, instance, secret);
160
228
  }
161
- async addAccount(artifact, instance, secret) {
229
+ async registerContractAndAddAccount(artifact, instance, secret) {
162
230
  const partialAddress = await computePartialAddress(instance);
163
231
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
164
232
  await this.contractStore.addContractInstance(instance);
165
233
  await this.contractStore.addContractArtifact(artifact);
166
- const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
234
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
167
235
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
168
236
  await this.addressStore.addCompleteAddress(completeAddress);
169
237
  this.logger.debug(`Created account ${completeAddress.address}`);
170
238
  return completeAddress;
171
239
  }
172
- async createAccount(secret) {
173
- // This is a foot gun !
174
- const completeAddress = await this.keyStore.addAccount(secret, secret);
240
+ async createAccount(secret, partialAddress) {
241
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
175
242
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
176
243
  await this.addressStore.addCompleteAddress(completeAddress);
177
244
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -179,14 +246,39 @@ export class TXEOracleTopLevelContext {
179
246
  }
180
247
  async addAuthWitness(address, messageHash) {
181
248
  const account = await this.accountStore.getAccount(address);
182
- const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
249
+ const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
250
+ const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
183
251
  const schnorr = new Schnorr();
184
- const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
185
- const authWitness = new AuthWitness(messageHash, [
186
- ...signature.toBuffer()
187
- ]);
252
+ const signature = await schnorr.constructSignature(messageHash, privateKey);
253
+ const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
188
254
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
189
255
  }
256
+ setTaggingSecretStrategies(unconstrainedStrategy, constrainedStrategy) {
257
+ const apply = (mode, strategy)=>{
258
+ if (strategy.isSome()) {
259
+ this.taggingSecretStrategies.set(mode, strategy.value);
260
+ } else {
261
+ this.taggingSecretStrategies.delete(mode);
262
+ }
263
+ };
264
+ apply(AppTaggingSecretKind.UNCONSTRAINED, unconstrainedStrategy);
265
+ apply(AppTaggingSecretKind.CONSTRAINED, constrainedStrategy);
266
+ }
267
+ setAuthorizeAllUtilityCallTargets(authorizeAll) {
268
+ this.authorizeAllUtilityCallTargets = authorizeAll;
269
+ }
270
+ async sendL1ToL2Message(content, secretHash, sender, recipient) {
271
+ // Messages are appended to the tree, so the next free slot is simply the current tree size.
272
+ const { size } = await this.stateMachine.synchronizer.getCommitted().getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
273
+ const leafIndex = new Fr(size);
274
+ const message = new L1ToL2Message(new L1Actor(sender, this.chainId.toNumber()), new L2Actor(recipient, this.version.toNumber()), content, secretHash, leafIndex);
275
+ await this.mineBlock({
276
+ l1ToL2Messages: [
277
+ message.hash()
278
+ ]
279
+ });
280
+ return leafIndex;
281
+ }
190
282
  async mineBlock(options = {}) {
191
283
  const blockNumber = await this.getNextBlockNumber();
192
284
  const txEffect = TxEffect.empty();
@@ -196,7 +288,7 @@ export class TXEOracleTopLevelContext {
196
288
  ];
197
289
  txEffect.txHash = new TxHash(new Fr(blockNumber));
198
290
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
199
- await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
291
+ await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
200
292
  const globals = makeGlobalVariables(undefined, {
201
293
  blockNumber,
202
294
  timestamp: this.nextBlockTimestamp,
@@ -208,31 +300,32 @@ export class TXEOracleTopLevelContext {
208
300
  ]);
209
301
  await forkedWorldTrees.close();
210
302
  this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
211
- await this.stateMachine.handleL2Block(block);
303
+ await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
212
304
  }
213
- async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, jobId) {
214
- this.logger.verbose(`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
215
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
305
+ async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, additionalScopes = [], jobId, authorizedUtilityCallTargets, gasSettings) {
306
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
307
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
308
+ this.logger.verbose(`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
309
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
216
310
  if (!artifact) {
217
311
  const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)')) ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.' : 'Function Artifact does not exist';
218
312
  throw new Error(message);
219
313
  }
220
- // When `from` is the zero address (e.g. when deploying a new account contract), we return an
221
- // empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
222
- const effectiveScopes = from.isZero() ? [] : [
223
- from
314
+ const scopes = from === undefined ? additionalScopes : [
315
+ from,
316
+ ...additionalScopes
224
317
  ];
225
318
  // Sync notes before executing private function to discover notes from previous transactions
226
319
  const utilityExecutor = async (call, execScopes)=>{
227
- await this.executeUtilityCall(call, execScopes, jobId);
320
+ await this.executeUtilityCall(call, {
321
+ scopes: execScopes,
322
+ jobId
323
+ });
228
324
  };
229
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
230
- await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, effectiveScopes);
325
+ await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, scopes);
231
326
  const blockNumber = await this.getNextBlockNumber();
232
- const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
233
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
234
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
235
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
327
+ const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
328
+ const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
236
329
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
237
330
  const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
238
331
  const noteCache = new ExecutionNoteCache(protocolNullifier);
@@ -243,9 +336,12 @@ export class TXEOracleTopLevelContext {
243
336
  await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
244
337
  const taggingIndexCache = new ExecutionTaggingIndexCache();
245
338
  const simulator = new WASMSimulator();
339
+ const transientArrayService = new TransientArrayService();
246
340
  const privateExecutionOracle = new PrivateExecutionOracle({
247
341
  argsHash,
248
342
  txContext,
343
+ // The TXE does not run the init kernel's salt binding, so no tx-request salt is in scope.
344
+ txRequestSalt: Fr.ZERO,
249
345
  callContext,
250
346
  anchorBlockHeader: blockHeader,
251
347
  utilityExecutor,
@@ -256,25 +352,33 @@ export class TXEOracleTopLevelContext {
256
352
  ]),
257
353
  noteCache,
258
354
  taggingIndexCache,
259
- contractStore: this.contractStore,
355
+ anchoredContractData,
260
356
  noteStore: this.noteStore,
261
357
  keyStore: this.keyStore,
262
358
  addressStore: this.addressStore,
263
359
  aztecNode: this.stateMachine.node,
264
360
  senderTaggingStore: this.senderTaggingStore,
265
361
  recipientTaggingStore: this.recipientTaggingStore,
266
- senderAddressBookStore: this.senderAddressBookStore,
267
- capsuleStore: this.capsuleStore,
362
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
363
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
364
+ factService: new FactService(this.factStore, scopes),
268
365
  privateEventStore: this.privateEventStore,
269
366
  contractSyncService: this.stateMachine.contractSyncService,
270
367
  jobId,
271
368
  totalPublicCalldataCount: 0,
272
369
  sideEffectCounter: minRevertibleSideEffectCounter,
273
- scopes: effectiveScopes,
370
+ scopes,
274
371
  // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
275
372
  // contract would perform, including setting senderForTags.
276
373
  senderForTags: from,
277
- simulator
374
+ simulator,
375
+ txResolver: this.stateMachine.txResolver,
376
+ l2TipsStore: this.stateMachine.l2TipsProvider,
377
+ hooks: composeHooks({
378
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(isStaticCall ? 'private view' : 'private', authorizedUtilityCallTargets),
379
+ resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies)
380
+ }),
381
+ transientArrayService
278
382
  });
279
383
  // 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.
280
384
  let result;
@@ -287,10 +391,9 @@ export class TXEOracleTopLevelContext {
287
391
  r.publicInputs.publicTeardownCallRequest
288
392
  ]));
289
393
  const publicFunctionsCalldata = await Promise.all(publicCallRequests.map(async (r)=>{
290
- const calldata = await privateExecutionOracle.loadFromExecutionCache(r.calldataHash);
394
+ const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
291
395
  return new HashedValues(calldata, r.calldataHash);
292
396
  }));
293
- noteCache.finish();
294
397
  const nonceGenerator = noteCache.getNonceGenerator();
295
398
  result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
296
399
  } catch (err) {
@@ -299,7 +402,7 @@ export class TXEOracleTopLevelContext {
299
402
  // According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
300
403
  // the nonce generator for the note hashes.
301
404
  // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
302
- const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>this.contractStore.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
405
+ const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>anchoredContractData.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
303
406
  const globals = makeGlobalVariables();
304
407
  globals.blockNumber = blockNumber;
305
408
  globals.timestamp = this.nextBlockTimestamp;
@@ -338,7 +441,7 @@ export class TXEOracleTopLevelContext {
338
441
  } else if (!processedTx.revertCode.isOK()) {
339
442
  if (processedTx.revertReason) {
340
443
  try {
341
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
444
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, await this.stateMachine.anchorBlockStore.getBlockHeader(), this.logger);
342
445
  // eslint-disable-next-line no-empty
343
446
  } catch {}
344
447
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -346,10 +449,20 @@ export class TXEOracleTopLevelContext {
346
449
  throw new Error('Contract execution has reverted');
347
450
  }
348
451
  }
452
+ // Walk the nested private-call tree and collect every offchain effect the transaction emitted.
453
+ // PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
454
+ // `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
455
+ // we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
456
+ const offchainEffects = collectNested([
457
+ executionResult
458
+ ], (r)=>r.offchainEffects.map((e)=>e.data));
349
459
  if (isStaticCall) {
350
460
  await checkpoint.revert();
351
461
  await forkedWorldTrees.close();
352
- return executionResult.returnValues ?? [];
462
+ return {
463
+ returnValues: executionResult.returnValues ?? [],
464
+ offchainEffects
465
+ };
353
466
  }
354
467
  const txEffect = TxEffect.empty();
355
468
  txEffect.noteHashes = processedTx.txEffect.noteHashes;
@@ -365,16 +478,17 @@ export class TXEOracleTopLevelContext {
365
478
  ]);
366
479
  await this.stateMachine.handleL2Block(l2Block);
367
480
  await forkedWorldTrees.close();
368
- return executionResult.returnValues ?? [];
481
+ return {
482
+ returnValues: executionResult.returnValues ?? [],
483
+ offchainEffects
484
+ };
369
485
  }
370
- async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall) {
371
- this.logger.verbose(`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
486
+ async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall, gasSettings) {
487
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
488
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
489
+ this.logger.verbose(`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
372
490
  const blockNumber = await this.getNextBlockNumber();
373
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
374
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
375
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
376
491
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
377
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
378
492
  const calldataHash = await computeCalldataHash(calldata);
379
493
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
380
494
  const globals = makeGlobalVariables();
@@ -405,7 +519,7 @@ export class TXEOracleTopLevelContext {
405
519
  // The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
406
520
  // may require producing reverts.
407
521
  const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
408
- revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from, targetContractAddress, isStaticCall, calldataHash);
522
+ revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from ?? AztecAddress.NULL_MSG_SENDER, targetContractAddress, isStaticCall, calldataHash);
409
523
  const inputsForPublic = new PartialPrivateTailPublicInputsForPublic(nonRevertibleAccumulatedData, revertibleAccumulatedData, PublicCallRequest.empty());
410
524
  const constantData = new TxConstantData(anchorBlockHeader, txContext, Fr.zero(), Fr.zero());
411
525
  const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*expirationTimestamp=*/ 0n, inputsForPublic, undefined);
@@ -431,7 +545,7 @@ export class TXEOracleTopLevelContext {
431
545
  } else if (!processedTx.revertCode.isOK()) {
432
546
  if (processedTx.revertReason) {
433
547
  try {
434
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
548
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader, this.logger);
435
549
  // eslint-disable-next-line no-empty
436
550
  } catch {}
437
551
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -461,16 +575,20 @@ export class TXEOracleTopLevelContext {
461
575
  await forkedWorldTrees.close();
462
576
  return returnValues ?? [];
463
577
  }
464
- async executeUtilityFunction(targetContractAddress, functionSelector, args, jobId) {
465
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
578
+ async executeUtilityFunction(from, targetContractAddress, functionSelector, args, jobId, authorizedUtilityCallTargets) {
579
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
580
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
581
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
466
582
  if (!artifact) {
467
583
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
468
584
  }
469
585
  // Sync notes before executing utility function to discover notes from previous transactions
470
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
471
586
  await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, async (call, execScopes)=>{
472
- await this.executeUtilityCall(call, execScopes, jobId);
473
- }, blockHeader, jobId, 'ALL_SCOPES');
587
+ await this.executeUtilityCall(call, {
588
+ scopes: execScopes,
589
+ jobId
590
+ });
591
+ }, blockHeader, jobId, await this.keyStore.getAccounts());
474
592
  const call = FunctionCall.from({
475
593
  name: artifact.name,
476
594
  to: targetContractAddress,
@@ -481,10 +599,20 @@ export class TXEOracleTopLevelContext {
481
599
  args,
482
600
  returnTypes: []
483
601
  });
484
- return this.executeUtilityCall(call, 'ALL_SCOPES', jobId);
602
+ return this.executeUtilityCall(call, {
603
+ from,
604
+ scopes: await this.keyStore.getAccounts(),
605
+ jobId,
606
+ authorizedUtilityCallTargets
607
+ });
485
608
  }
486
- async executeUtilityCall(call, scopes, jobId) {
487
- const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
609
+ async executeUtilityCall(call, { from = AztecAddress.NULL_MSG_SENDER, scopes, jobId, authorizedUtilityCallTargets = [] }) {
610
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
611
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
612
+ const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
613
+ if (!entryPointArtifact) {
614
+ throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
615
+ }
488
616
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
489
617
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
490
618
  }
@@ -493,25 +621,48 @@ export class TXEOracleTopLevelContext {
493
621
  selector: call.selector
494
622
  });
495
623
  try {
496
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
624
+ const simulator = new WASMSimulator();
625
+ const utilityExecutor = async (syncCall, execScopes)=>{
626
+ await this.executeUtilityCall(syncCall, {
627
+ scopes: execScopes,
628
+ jobId,
629
+ authorizedUtilityCallTargets
630
+ });
631
+ };
497
632
  const oracle = new UtilityExecutionOracle({
498
- contractAddress: call.to,
633
+ callContext: CallContext.from({
634
+ msgSender: from,
635
+ contractAddress: call.to,
636
+ functionSelector: call.selector,
637
+ isStaticCall: true
638
+ }),
499
639
  authWitnesses: [],
500
640
  capsules: [],
501
641
  anchorBlockHeader,
502
- contractStore: this.contractStore,
642
+ anchoredContractData,
503
643
  noteStore: this.noteStore,
504
644
  keyStore: this.keyStore,
505
645
  addressStore: this.addressStore,
506
646
  aztecNode: this.stateMachine.node,
507
647
  recipientTaggingStore: this.recipientTaggingStore,
508
- senderAddressBookStore: this.senderAddressBookStore,
509
- capsuleStore: this.capsuleStore,
648
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
649
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
650
+ factService: new FactService(this.factStore, scopes),
510
651
  privateEventStore: this.privateEventStore,
652
+ txResolver: this.stateMachine.txResolver,
653
+ contractSyncService: this.stateMachine.contractSyncService,
654
+ l2TipsStore: this.stateMachine.l2TipsProvider,
511
655
  jobId,
512
- scopes
656
+ scopes,
657
+ simulator,
658
+ utilityExecutor,
659
+ hooks: composeHooks({
660
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets)
661
+ }),
662
+ // Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
663
+ transientArrayService: new TransientArrayService()
513
664
  });
514
- const acirExecutionResult = await new WASMSimulator().executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback()).catch((err)=>{
665
+ const acirExecutionResult = await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle)).catch((err)=>{
515
666
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
516
667
  throw new ExecutionError(err.message, {
517
668
  contractAddress: call.to,
@@ -528,13 +679,33 @@ export class TXEOracleTopLevelContext {
528
679
  }
529
680
  close() {
530
681
  this.logger.debug('Exiting Top Level Context');
531
- return [
532
- this.nextBlockTimestamp,
533
- this.authwits
534
- ];
682
+ return {
683
+ nextBlockTimestamp: this.nextBlockTimestamp,
684
+ authwits: this.authwits,
685
+ taggingSecretStrategies: this.taggingSecretStrategies,
686
+ authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets
687
+ };
535
688
  }
536
689
  async getLastBlockNumber() {
537
- const header = await this.stateMachine.node.getBlockHeader('latest');
538
- return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
690
+ const block = await this.stateMachine.node.getBlock('latest');
691
+ return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
692
+ }
693
+ buildAuthorizeUtilityCallHook(callerContext, authorizedTargets) {
694
+ if (this.authorizeAllUtilityCallTargets) {
695
+ return authorizeAllUtilityCallsHook;
696
+ }
697
+ if (authorizedTargets.length === 0) {
698
+ return undefined;
699
+ }
700
+ return (req)=>Promise.resolve({
701
+ authorized: req.callerContext === callerContext && authorizedTargets.some((t)=>t.equals(req.target))
702
+ });
539
703
  }
540
704
  }
705
+ /**
706
+ * An `authorizeUtilityCall` hook that authorizes every cross-contract utility call.
707
+ *
708
+ * Backs the `aztec_txe_setAuthorizeAllUtilityCallTargets` oracle.
709
+ */ export const authorizeAllUtilityCallsHook = ()=>Promise.resolve({
710
+ authorized: true
711
+ });