@aztec/txe 0.0.1-commit.3fd054f6 → 0.0.1-commit.431c48d

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-LVLJKGGH.js +266 -0
  30. package/dest/chunk-LVLJKGGH.js.map +7 -0
  31. package/dest/chunk-OVMCQ5A6.js +304 -0
  32. package/dest/chunk-OVMCQ5A6.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 +40494 -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 -18
  67. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  68. package/dest/oracle/txe_oracle_top_level_context.js +288 -98
  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 -233
  79. package/dest/rpc_translator.d.ts.map +1 -1
  80. package/dest/rpc_translator.js +791 -636
  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 +4 -3
  84. package/dest/state_machine/archiver.d.ts.map +1 -1
  85. package/dest/state_machine/archiver.js +24 -14
  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 -7
  93. package/dest/state_machine/index.d.ts.map +1 -1
  94. package/dest/state_machine/index.js +52 -14
  95. package/dest/state_machine/mock_epoch_cache.d.ts +1 -2
  96. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  97. package/dest/state_machine/mock_epoch_cache.js +0 -3
  98. package/dest/state_machine/synchronizer.d.ts +5 -2
  99. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  100. package/dest/state_machine/synchronizer.js +7 -3
  101. package/dest/txe_session.d.ts +90 -20
  102. package/dest/txe_session.d.ts.map +1 -1
  103. package/dest/txe_session.js +319 -73
  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 +7 -4
  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 +364 -121
  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 +880 -902
  148. package/src/state_machine/archiver.ts +37 -16
  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 -32
  152. package/src/state_machine/mock_epoch_cache.ts +0 -4
  153. package/src/state_machine/synchronizer.ts +9 -3
  154. package/src/txe_session.ts +554 -89
  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 -4
  160. package/src/worker.ts +98 -0
  161. package/dest/util/encoding.d.ts +0 -788
  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,18 +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;
43
- contractSyncService;
48
+ taggingSecretStrategies;
49
+ authorizeAllUtilityCallTargets;
50
+ artifactResolver;
51
+ rootPath;
52
+ packageName;
44
53
  isMisc;
45
54
  isTxe;
46
55
  logger;
47
- constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits, contractSyncService){
56
+ constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, taggingSecretSourcesStore, capsuleStore, factStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits, taggingSecretStrategies, authorizeAllUtilityCallTargets, artifactResolver, rootPath, packageName){
48
57
  this.stateMachine = stateMachine;
49
58
  this.contractStore = contractStore;
50
59
  this.noteStore = noteStore;
@@ -53,23 +62,38 @@ export class TXEOracleTopLevelContext {
53
62
  this.accountStore = accountStore;
54
63
  this.senderTaggingStore = senderTaggingStore;
55
64
  this.recipientTaggingStore = recipientTaggingStore;
56
- this.senderAddressBookStore = senderAddressBookStore;
65
+ this.taggingSecretSourcesStore = taggingSecretSourcesStore;
57
66
  this.capsuleStore = capsuleStore;
67
+ this.factStore = factStore;
58
68
  this.privateEventStore = privateEventStore;
59
69
  this.nextBlockTimestamp = nextBlockTimestamp;
60
70
  this.version = version;
61
71
  this.chainId = chainId;
62
72
  this.authwits = authwits;
63
- this.contractSyncService = contractSyncService;
73
+ this.taggingSecretStrategies = taggingSecretStrategies;
74
+ this.authorizeAllUtilityCallTargets = authorizeAllUtilityCallTargets;
75
+ this.artifactResolver = artifactResolver;
76
+ this.rootPath = rootPath;
77
+ this.packageName = packageName;
64
78
  this.isMisc = true;
65
79
  this.isTxe = true;
66
80
  this.logger = createLogger('txe:top_level_context');
67
81
  this.logger.debug('Entering Top Level Context');
68
82
  }
69
- assertCompatibleOracleVersion(version) {
70
- if (version !== ORACLE_VERSION) {
71
- 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})`);
72
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;
73
97
  }
74
98
  // This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
75
99
  // setup.
@@ -77,7 +101,7 @@ export class TXEOracleTopLevelContext {
77
101
  return Fr.random();
78
102
  }
79
103
  // We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
80
- log(level, message, fields) {
104
+ log(level, message, _fieldsSize, fields) {
81
105
  if (!LogLevels[level]) {
82
106
  throw new Error(`Invalid log level: ${level}`);
83
107
  }
@@ -97,20 +121,27 @@ export class TXEOracleTopLevelContext {
97
121
  return Promise.resolve(this.nextBlockTimestamp);
98
122
  }
99
123
  async getLastBlockTimestamp() {
100
- return (await this.stateMachine.node.getBlockHeader('latest')).globalVariables.timestamp;
124
+ return (await this.stateMachine.node.getBlockData('latest')).header.globalVariables.timestamp;
101
125
  }
102
126
  async getLastTxEffects() {
103
127
  const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
104
- const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
128
+ const block = await this.stateMachine.archiver.getBlock({
129
+ number: latestBlockNumber
130
+ });
105
131
  if (block.body.txEffects.length != 1) {
106
132
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
107
133
  throw new Error(`Expected a single transaction in the last block, found ${block.body.txEffects.length}`);
108
134
  }
109
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
+ }
110
140
  return {
111
141
  txHash: txEffects.txHash,
112
142
  noteHashes: txEffects.noteHashes,
113
- nullifiers: txEffects.nullifiers
143
+ nullifiers: txEffects.nullifiers,
144
+ privateLogs
114
145
  };
115
146
  }
116
147
  async syncContractNonOracleMethod(contractAddress, scope, jobId) {
@@ -118,15 +149,26 @@ export class TXEOracleTopLevelContext {
118
149
  this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
119
150
  return;
120
151
  }
121
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
122
- await this.stateMachine.contractSyncService.ensureContractSynced(contractAddress, null, async (call, execScopes)=>{
123
- await this.executeUtilityCall(call, execScopes, jobId);
124
- }, blockHeader, jobId, [
125
- scope
126
- ]);
152
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
153
+ await this.stateMachine.contractSyncService.ensureContractSynced({
154
+ contract: contractAddress,
155
+ functionToInvokeAfterSync: null,
156
+ utilityExecutor: async (call, execScopes)=>{
157
+ await this.executeUtilityCall(call, {
158
+ scopes: execScopes,
159
+ jobId
160
+ });
161
+ },
162
+ anchorBlockHeader,
163
+ jobId,
164
+ scopes: [
165
+ scope
166
+ ],
167
+ triggeredBy: undefined
168
+ });
127
169
  }
128
170
  async getPrivateEvents(selector, contractAddress, scope) {
129
- return (await this.privateEventStore.getPrivateEvents(selector, {
171
+ const events = (await this.privateEventStore.getPrivateEvents(selector, {
130
172
  contractAddress,
131
173
  scopes: [
132
174
  scope
@@ -134,6 +176,13 @@ export class TXEOracleTopLevelContext {
134
176
  fromBlock: 0,
135
177
  toBlock: await this.getLastBlockNumber() + 1
136
178
  })).map((e)=>e.packedEvent);
179
+ if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
180
+ throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
181
+ }
182
+ if (events.some((e)=>e.length > MAX_PRIVATE_EVENT_LEN)) {
183
+ throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
184
+ }
185
+ return events;
137
186
  }
138
187
  async advanceBlocksBy(blocks) {
139
188
  this.logger.debug(`time traveling ${blocks} blocks`);
@@ -145,35 +194,59 @@ export class TXEOracleTopLevelContext {
145
194
  this.logger.debug(`time traveling ${duration} seconds`);
146
195
  this.nextBlockTimestamp += duration;
147
196
  }
148
- async deploy(artifact, instance, secret) {
197
+ deploymentNullifier(address) {
198
+ return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
199
+ }
200
+ async deploy(contractPath, initializer, args, secret, salt, deployer) {
201
+ const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
202
+ rootPath: this.rootPath,
203
+ packageName: this.packageName,
204
+ contractPath,
205
+ initializer,
206
+ args,
207
+ secret,
208
+ salt,
209
+ deployer
210
+ });
149
211
  // Emit deployment nullifier
150
212
  await this.mineBlock({
151
213
  nullifiers: [
152
- await siloNullifier(AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), instance.address.toField())
214
+ await this.deploymentNullifier(instance.address)
153
215
  ]
154
216
  });
155
217
  if (!secret.equals(Fr.ZERO)) {
156
- await this.addAccount(artifact, instance, secret);
218
+ await this.registerContractAndAddAccount(artifact, instance, secret);
157
219
  } else {
158
220
  await this.contractStore.addContractInstance(instance);
159
221
  await this.contractStore.addContractArtifact(artifact);
160
222
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
161
223
  }
224
+ return CONTRACT_INSTANCE.serialization.fn(instance).flat();
225
+ }
226
+ /**
227
+ * Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
228
+ */ async mineDeploymentNullifiers(addresses) {
229
+ await this.mineBlock({
230
+ nullifiers: await Promise.all(addresses.map((address)=>this.deploymentNullifier(address)))
231
+ });
232
+ }
233
+ async addAccount(secret) {
234
+ const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
235
+ return this.registerContractAndAddAccount(artifact, instance, secret);
162
236
  }
163
- async addAccount(artifact, instance, secret) {
237
+ async registerContractAndAddAccount(artifact, instance, secret) {
164
238
  const partialAddress = await computePartialAddress(instance);
165
239
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
166
240
  await this.contractStore.addContractInstance(instance);
167
241
  await this.contractStore.addContractArtifact(artifact);
168
- const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
242
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
169
243
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
170
244
  await this.addressStore.addCompleteAddress(completeAddress);
171
245
  this.logger.debug(`Created account ${completeAddress.address}`);
172
246
  return completeAddress;
173
247
  }
174
- async createAccount(secret) {
175
- // This is a foot gun !
176
- const completeAddress = await this.keyStore.addAccount(secret, secret);
248
+ async createAccount(secret, partialAddress) {
249
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
177
250
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
178
251
  await this.addressStore.addCompleteAddress(completeAddress);
179
252
  this.logger.debug(`Created account ${completeAddress.address}`);
@@ -181,14 +254,39 @@ export class TXEOracleTopLevelContext {
181
254
  }
182
255
  async addAuthWitness(address, messageHash) {
183
256
  const account = await this.accountStore.getAccount(address);
184
- const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
257
+ const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
258
+ const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
185
259
  const schnorr = new Schnorr();
186
- const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
187
- const authWitness = new AuthWitness(messageHash, [
188
- ...signature.toBuffer()
189
- ]);
260
+ const signature = await schnorr.constructSignature(messageHash, privateKey);
261
+ const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
190
262
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
191
263
  }
264
+ setTaggingSecretStrategies(unconstrainedStrategy, constrainedStrategy) {
265
+ const apply = (mode, strategy)=>{
266
+ if (strategy.isSome()) {
267
+ this.taggingSecretStrategies.set(mode, strategy.value);
268
+ } else {
269
+ this.taggingSecretStrategies.delete(mode);
270
+ }
271
+ };
272
+ apply(AppTaggingSecretKind.UNCONSTRAINED, unconstrainedStrategy);
273
+ apply(AppTaggingSecretKind.CONSTRAINED, constrainedStrategy);
274
+ }
275
+ setAuthorizeAllUtilityCallTargets(authorizeAll) {
276
+ this.authorizeAllUtilityCallTargets = authorizeAll;
277
+ }
278
+ async sendL1ToL2Message(content, secretHash, sender, recipient) {
279
+ // Messages are appended to the tree, so the next free slot is simply the current tree size.
280
+ const { size } = await this.stateMachine.synchronizer.getCommitted().getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
281
+ const leafIndex = new Fr(size);
282
+ const message = new L1ToL2Message(new L1Actor(sender, this.chainId.toNumber()), new L2Actor(recipient, this.version.toNumber()), content, secretHash, leafIndex);
283
+ await this.mineBlock({
284
+ l1ToL2Messages: [
285
+ message.hash()
286
+ ]
287
+ });
288
+ return leafIndex;
289
+ }
192
290
  async mineBlock(options = {}) {
193
291
  const blockNumber = await this.getNextBlockNumber();
194
292
  const txEffect = TxEffect.empty();
@@ -198,7 +296,7 @@ export class TXEOracleTopLevelContext {
198
296
  ];
199
297
  txEffect.txHash = new TxHash(new Fr(blockNumber));
200
298
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
201
- await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
299
+ await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
202
300
  const globals = makeGlobalVariables(undefined, {
203
301
  blockNumber,
204
302
  timestamp: this.nextBlockTimestamp,
@@ -210,31 +308,40 @@ export class TXEOracleTopLevelContext {
210
308
  ]);
211
309
  await forkedWorldTrees.close();
212
310
  this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
213
- await this.stateMachine.handleL2Block(block);
311
+ await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
214
312
  }
215
- async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, jobId) {
216
- this.logger.verbose(`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
217
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
313
+ async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, additionalScopes = [], jobId, authorizedUtilityCallTargets, gasSettings) {
314
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
315
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
316
+ this.logger.verbose(`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
317
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
218
318
  if (!artifact) {
219
319
  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';
220
320
  throw new Error(message);
221
321
  }
222
- // When `from` is the zero address (e.g. when deploying a new account contract), we return an
223
- // empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
224
- const effectiveScopes = from.isZero() ? [] : [
225
- from
322
+ const scopes = from === undefined ? additionalScopes : [
323
+ from,
324
+ ...additionalScopes
226
325
  ];
227
326
  // Sync notes before executing private function to discover notes from previous transactions
228
327
  const utilityExecutor = async (call, execScopes)=>{
229
- await this.executeUtilityCall(call, execScopes, jobId);
328
+ await this.executeUtilityCall(call, {
329
+ scopes: execScopes,
330
+ jobId
331
+ });
230
332
  };
231
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
232
- await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, effectiveScopes);
333
+ await this.stateMachine.contractSyncService.ensureContractSynced({
334
+ contract: targetContractAddress,
335
+ functionToInvokeAfterSync: functionSelector,
336
+ utilityExecutor,
337
+ anchorBlockHeader: blockHeader,
338
+ jobId,
339
+ scopes,
340
+ triggeredBy: undefined
341
+ });
233
342
  const blockNumber = await this.getNextBlockNumber();
234
- const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
235
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
236
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
237
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
343
+ const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
344
+ const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
238
345
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
239
346
  const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
240
347
  const noteCache = new ExecutionNoteCache(protocolNullifier);
@@ -245,9 +352,12 @@ export class TXEOracleTopLevelContext {
245
352
  await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
246
353
  const taggingIndexCache = new ExecutionTaggingIndexCache();
247
354
  const simulator = new WASMSimulator();
355
+ const transientArrayService = new TransientArrayService();
248
356
  const privateExecutionOracle = new PrivateExecutionOracle({
249
357
  argsHash,
250
358
  txContext,
359
+ // The TXE does not run the init kernel's salt binding, so no tx-request salt is in scope.
360
+ txRequestSalt: Fr.ZERO,
251
361
  callContext,
252
362
  anchorBlockHeader: blockHeader,
253
363
  utilityExecutor,
@@ -258,26 +368,33 @@ export class TXEOracleTopLevelContext {
258
368
  ]),
259
369
  noteCache,
260
370
  taggingIndexCache,
261
- contractStore: this.contractStore,
371
+ anchoredContractData,
262
372
  noteStore: this.noteStore,
263
373
  keyStore: this.keyStore,
264
374
  addressStore: this.addressStore,
265
375
  aztecNode: this.stateMachine.node,
266
376
  senderTaggingStore: this.senderTaggingStore,
267
377
  recipientTaggingStore: this.recipientTaggingStore,
268
- senderAddressBookStore: this.senderAddressBookStore,
269
- capsuleStore: this.capsuleStore,
378
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
379
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
380
+ factService: new FactService(this.factStore, scopes),
270
381
  privateEventStore: this.privateEventStore,
271
382
  contractSyncService: this.stateMachine.contractSyncService,
272
383
  jobId,
273
384
  totalPublicCalldataCount: 0,
274
385
  sideEffectCounter: minRevertibleSideEffectCounter,
275
- scopes: effectiveScopes,
386
+ scopes,
276
387
  // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
277
388
  // contract would perform, including setting senderForTags.
278
389
  senderForTags: from,
279
390
  simulator,
280
- messageContextService: this.stateMachine.messageContextService
391
+ txResolver: this.stateMachine.txResolver,
392
+ l2TipsStore: this.stateMachine.l2TipsProvider,
393
+ hooks: composeHooks({
394
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(isStaticCall ? 'private view' : 'private', authorizedUtilityCallTargets),
395
+ resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies)
396
+ }),
397
+ transientArrayService
281
398
  });
282
399
  // 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.
283
400
  let result;
@@ -290,10 +407,9 @@ export class TXEOracleTopLevelContext {
290
407
  r.publicInputs.publicTeardownCallRequest
291
408
  ]));
292
409
  const publicFunctionsCalldata = await Promise.all(publicCallRequests.map(async (r)=>{
293
- const calldata = await privateExecutionOracle.loadFromExecutionCache(r.calldataHash);
410
+ const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
294
411
  return new HashedValues(calldata, r.calldataHash);
295
412
  }));
296
- noteCache.finish();
297
413
  const nonceGenerator = noteCache.getNonceGenerator();
298
414
  result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
299
415
  } catch (err) {
@@ -302,7 +418,7 @@ export class TXEOracleTopLevelContext {
302
418
  // According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
303
419
  // the nonce generator for the note hashes.
304
420
  // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
305
- const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>this.contractStore.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
421
+ const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>anchoredContractData.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
306
422
  const globals = makeGlobalVariables();
307
423
  globals.blockNumber = blockNumber;
308
424
  globals.timestamp = this.nextBlockTimestamp;
@@ -341,7 +457,7 @@ export class TXEOracleTopLevelContext {
341
457
  } else if (!processedTx.revertCode.isOK()) {
342
458
  if (processedTx.revertReason) {
343
459
  try {
344
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
460
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, await this.stateMachine.anchorBlockStore.getBlockHeader(), this.logger);
345
461
  // eslint-disable-next-line no-empty
346
462
  } catch {}
347
463
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -349,10 +465,20 @@ export class TXEOracleTopLevelContext {
349
465
  throw new Error('Contract execution has reverted');
350
466
  }
351
467
  }
468
+ // Walk the nested private-call tree and collect every offchain effect the transaction emitted.
469
+ // PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
470
+ // `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
471
+ // we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
472
+ const offchainEffects = collectNested([
473
+ executionResult
474
+ ], (r)=>r.offchainEffects.map((e)=>e.data));
352
475
  if (isStaticCall) {
353
476
  await checkpoint.revert();
354
477
  await forkedWorldTrees.close();
355
- return executionResult.returnValues ?? [];
478
+ return {
479
+ returnValues: executionResult.returnValues ?? [],
480
+ offchainEffects
481
+ };
356
482
  }
357
483
  const txEffect = TxEffect.empty();
358
484
  txEffect.noteHashes = processedTx.txEffect.noteHashes;
@@ -368,16 +494,17 @@ export class TXEOracleTopLevelContext {
368
494
  ]);
369
495
  await this.stateMachine.handleL2Block(l2Block);
370
496
  await forkedWorldTrees.close();
371
- return executionResult.returnValues ?? [];
497
+ return {
498
+ returnValues: executionResult.returnValues ?? [],
499
+ offchainEffects
500
+ };
372
501
  }
373
- async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall) {
374
- this.logger.verbose(`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
502
+ async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall, gasSettings) {
503
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
504
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
505
+ this.logger.verbose(`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
375
506
  const blockNumber = await this.getNextBlockNumber();
376
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
377
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
378
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
379
507
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
380
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
381
508
  const calldataHash = await computeCalldataHash(calldata);
382
509
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
383
510
  const globals = makeGlobalVariables();
@@ -408,7 +535,7 @@ export class TXEOracleTopLevelContext {
408
535
  // The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
409
536
  // may require producing reverts.
410
537
  const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
411
- revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from, targetContractAddress, isStaticCall, calldataHash);
538
+ revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from ?? AztecAddress.NULL_MSG_SENDER, targetContractAddress, isStaticCall, calldataHash);
412
539
  const inputsForPublic = new PartialPrivateTailPublicInputsForPublic(nonRevertibleAccumulatedData, revertibleAccumulatedData, PublicCallRequest.empty());
413
540
  const constantData = new TxConstantData(anchorBlockHeader, txContext, Fr.zero(), Fr.zero());
414
541
  const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*expirationTimestamp=*/ 0n, inputsForPublic, undefined);
@@ -434,7 +561,7 @@ export class TXEOracleTopLevelContext {
434
561
  } else if (!processedTx.revertCode.isOK()) {
435
562
  if (processedTx.revertReason) {
436
563
  try {
437
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
564
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader, this.logger);
438
565
  // eslint-disable-next-line no-empty
439
566
  } catch {}
440
567
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -464,16 +591,28 @@ export class TXEOracleTopLevelContext {
464
591
  await forkedWorldTrees.close();
465
592
  return returnValues ?? [];
466
593
  }
467
- async executeUtilityFunction(targetContractAddress, functionSelector, args, jobId) {
468
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
594
+ async executeUtilityFunction(from, targetContractAddress, functionSelector, args, jobId, authorizedUtilityCallTargets) {
595
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
596
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
597
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
469
598
  if (!artifact) {
470
599
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
471
600
  }
472
601
  // Sync notes before executing utility function to discover notes from previous transactions
473
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
474
- await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, async (call, execScopes)=>{
475
- await this.executeUtilityCall(call, execScopes, jobId);
476
- }, blockHeader, jobId, 'ALL_SCOPES');
602
+ await this.stateMachine.contractSyncService.ensureContractSynced({
603
+ contract: targetContractAddress,
604
+ functionToInvokeAfterSync: functionSelector,
605
+ utilityExecutor: async (call, execScopes)=>{
606
+ await this.executeUtilityCall(call, {
607
+ scopes: execScopes,
608
+ jobId
609
+ });
610
+ },
611
+ anchorBlockHeader: blockHeader,
612
+ jobId,
613
+ scopes: await this.keyStore.getAccounts(),
614
+ triggeredBy: undefined
615
+ });
477
616
  const call = FunctionCall.from({
478
617
  name: artifact.name,
479
618
  to: targetContractAddress,
@@ -484,10 +623,20 @@ export class TXEOracleTopLevelContext {
484
623
  args,
485
624
  returnTypes: []
486
625
  });
487
- return this.executeUtilityCall(call, 'ALL_SCOPES', jobId);
626
+ return this.executeUtilityCall(call, {
627
+ from,
628
+ scopes: await this.keyStore.getAccounts(),
629
+ jobId,
630
+ authorizedUtilityCallTargets
631
+ });
488
632
  }
489
- async executeUtilityCall(call, scopes, jobId) {
490
- const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
633
+ async executeUtilityCall(call, { from = AztecAddress.NULL_MSG_SENDER, scopes, jobId, authorizedUtilityCallTargets = [] }) {
634
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
635
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
636
+ const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
637
+ if (!entryPointArtifact) {
638
+ throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
639
+ }
491
640
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
492
641
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
493
642
  }
@@ -496,27 +645,48 @@ export class TXEOracleTopLevelContext {
496
645
  selector: call.selector
497
646
  });
498
647
  try {
499
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
648
+ const simulator = new WASMSimulator();
649
+ const utilityExecutor = async (syncCall, execScopes)=>{
650
+ await this.executeUtilityCall(syncCall, {
651
+ scopes: execScopes,
652
+ jobId,
653
+ authorizedUtilityCallTargets
654
+ });
655
+ };
500
656
  const oracle = new UtilityExecutionOracle({
501
- contractAddress: call.to,
657
+ callContext: CallContext.from({
658
+ msgSender: from,
659
+ contractAddress: call.to,
660
+ functionSelector: call.selector,
661
+ isStaticCall: true
662
+ }),
502
663
  authWitnesses: [],
503
664
  capsules: [],
504
665
  anchorBlockHeader,
505
- contractStore: this.contractStore,
666
+ anchoredContractData,
506
667
  noteStore: this.noteStore,
507
668
  keyStore: this.keyStore,
508
669
  addressStore: this.addressStore,
509
670
  aztecNode: this.stateMachine.node,
510
671
  recipientTaggingStore: this.recipientTaggingStore,
511
- senderAddressBookStore: this.senderAddressBookStore,
512
- capsuleStore: this.capsuleStore,
672
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
673
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
674
+ factService: new FactService(this.factStore, scopes),
513
675
  privateEventStore: this.privateEventStore,
514
- messageContextService: this.stateMachine.messageContextService,
515
- contractSyncService: this.contractSyncService,
676
+ txResolver: this.stateMachine.txResolver,
677
+ contractSyncService: this.stateMachine.contractSyncService,
678
+ l2TipsStore: this.stateMachine.l2TipsProvider,
516
679
  jobId,
517
- scopes
680
+ scopes,
681
+ simulator,
682
+ utilityExecutor,
683
+ hooks: composeHooks({
684
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets)
685
+ }),
686
+ // Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
687
+ transientArrayService: new TransientArrayService()
518
688
  });
519
- const acirExecutionResult = await new WASMSimulator().executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback()).catch((err)=>{
689
+ const acirExecutionResult = await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle)).catch((err)=>{
520
690
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
521
691
  throw new ExecutionError(err.message, {
522
692
  contractAddress: call.to,
@@ -533,13 +703,33 @@ export class TXEOracleTopLevelContext {
533
703
  }
534
704
  close() {
535
705
  this.logger.debug('Exiting Top Level Context');
536
- return [
537
- this.nextBlockTimestamp,
538
- this.authwits
539
- ];
706
+ return {
707
+ nextBlockTimestamp: this.nextBlockTimestamp,
708
+ authwits: this.authwits,
709
+ taggingSecretStrategies: this.taggingSecretStrategies,
710
+ authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets
711
+ };
540
712
  }
541
713
  async getLastBlockNumber() {
542
- const header = await this.stateMachine.node.getBlockHeader('latest');
543
- return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
714
+ const block = await this.stateMachine.node.getBlock('latest');
715
+ return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
716
+ }
717
+ buildAuthorizeUtilityCallHook(callerContext, authorizedTargets) {
718
+ if (this.authorizeAllUtilityCallTargets) {
719
+ return authorizeAllUtilityCallsHook;
720
+ }
721
+ if (authorizedTargets.length === 0) {
722
+ return undefined;
723
+ }
724
+ return (req)=>Promise.resolve({
725
+ authorized: req.callerContext === callerContext && authorizedTargets.some((t)=>t.equals(req.target))
726
+ });
544
727
  }
545
728
  }
729
+ /**
730
+ * An `authorizeUtilityCall` hook that authorizes every cross-contract utility call.
731
+ *
732
+ * Backs the `aztec_txe_setAuthorizeAllUtilityCallTargets` oracle.
733
+ */ export const authorizeAllUtilityCallsHook = ()=>Promise.resolve({
734
+ authorized: true
735
+ });