@aztec/txe 0.0.1-commit.4d79d1f2d → 0.0.1-commit.4d9804df

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 (174) hide show
  1. package/dest/AuthRegistry-QVGDDH5X.js +3 -0
  2. package/dest/AuthRegistry-QVGDDH5X.js.map +7 -0
  3. package/dest/ContractClassRegistry-VWR3F42P.js +3 -0
  4. package/dest/ContractClassRegistry-VWR3F42P.js.map +7 -0
  5. package/dest/ContractInstanceRegistry-FHIWE33X.js +3 -0
  6. package/dest/ContractInstanceRegistry-FHIWE33X.js.map +7 -0
  7. package/dest/FeeJuice-SAOWVGG7.js +3 -0
  8. package/dest/FeeJuice-SAOWVGG7.js.map +7 -0
  9. package/dest/HandshakeRegistry-GY5CPEPS.js +3 -0
  10. package/dest/HandshakeRegistry-GY5CPEPS.js.map +7 -0
  11. package/dest/MultiCallEntrypoint-QG5H33ZZ.js +3 -0
  12. package/dest/MultiCallEntrypoint-QG5H33ZZ.js.map +7 -0
  13. package/dest/SchnorrAccount-NME3E45O.js +3 -0
  14. package/dest/SchnorrAccount-NME3E45O.js.map +7 -0
  15. package/dest/SchnorrInitializerlessAccount-WTGXU6SW.js +3 -0
  16. package/dest/SchnorrInitializerlessAccount-WTGXU6SW.js.map +7 -0
  17. package/dest/bin/check_txe_oracle_version.d.ts +2 -0
  18. package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
  19. package/dest/bin/check_txe_oracle_version.js +53 -0
  20. package/dest/bin/index.js +3 -30
  21. package/dest/bin/index.js.map +7 -0
  22. package/dest/bin/oracle_test_server.d.ts +3 -0
  23. package/dest/bin/oracle_test_server.d.ts.map +1 -0
  24. package/dest/bin/oracle_test_server.js +41 -0
  25. package/dest/chunk-32UHX7YY.js +3 -0
  26. package/dest/chunk-32UHX7YY.js.map +7 -0
  27. package/dest/chunk-GSUKUCKV.js +260 -0
  28. package/dest/chunk-GSUKUCKV.js.map +7 -0
  29. package/dest/chunk-UP4KKUVA.js +304 -0
  30. package/dest/chunk-UP4KKUVA.js.map +7 -0
  31. package/dest/constants.d.ts +5 -1
  32. package/dest/constants.d.ts.map +1 -1
  33. package/dest/constants.js +9 -1
  34. package/dest/dispatcher_pool.d.ts +67 -0
  35. package/dest/dispatcher_pool.d.ts.map +1 -0
  36. package/dest/dispatcher_pool.js +286 -0
  37. package/dest/index.d.ts +51 -7
  38. package/dest/index.d.ts.map +1 -1
  39. package/dest/index.js +73 -157
  40. package/dest/metafile.json +38759 -0
  41. package/dest/msgpackr_fr_extension.d.ts +2 -0
  42. package/dest/msgpackr_fr_extension.d.ts.map +1 -0
  43. package/dest/msgpackr_fr_extension.js +21 -0
  44. package/dest/oracle/interfaces.d.ts +69 -30
  45. package/dest/oracle/interfaces.d.ts.map +1 -1
  46. package/dest/oracle/tagging_secret_strategy.d.ts +12 -0
  47. package/dest/oracle/tagging_secret_strategy.d.ts.map +1 -0
  48. package/dest/oracle/tagging_secret_strategy.js +12 -0
  49. package/dest/oracle/test-resolver/default_fixtures.d.ts +16 -0
  50. package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
  51. package/dest/oracle/test-resolver/default_fixtures.js +200 -0
  52. package/dest/oracle/test-resolver/index.d.ts +9 -0
  53. package/dest/oracle/test-resolver/index.d.ts.map +1 -0
  54. package/dest/oracle/test-resolver/index.js +32 -0
  55. package/dest/oracle/test-resolver/resolver.d.ts +48 -0
  56. package/dest/oracle/test-resolver/resolver.d.ts.map +1 -0
  57. package/dest/oracle/test-resolver/resolver.js +181 -0
  58. package/dest/oracle/txe_oracle_public_context.d.ts +38 -14
  59. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  60. package/dest/oracle/txe_oracle_public_context.js +61 -13
  61. package/dest/oracle/txe_oracle_registry.d.ts +172 -0
  62. package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
  63. package/dest/oracle/txe_oracle_registry.js +767 -0
  64. package/dest/oracle/txe_oracle_top_level_context.d.ts +69 -29
  65. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  66. package/dest/oracle/txe_oracle_top_level_context.js +585 -316
  67. package/dest/oracle/txe_oracle_version.d.ts +17 -0
  68. package/dest/oracle/txe_oracle_version.d.ts.map +1 -0
  69. package/dest/oracle/txe_oracle_version.js +14 -0
  70. package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
  71. package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
  72. package/dest/oracle/txe_private_execution_oracle.js +15 -0
  73. package/dest/rpc_server.d.ts +14 -0
  74. package/dest/rpc_server.d.ts.map +1 -0
  75. package/dest/rpc_server.js +78 -0
  76. package/dest/rpc_translator.d.ts +115 -228
  77. package/dest/rpc_translator.d.ts.map +1 -1
  78. package/dest/rpc_translator.js +901 -624
  79. package/dest/server.bundle.js +3 -0
  80. package/dest/server.bundle.js.map +7 -0
  81. package/dest/state_machine/archiver.d.ts +6 -5
  82. package/dest/state_machine/archiver.d.ts.map +1 -1
  83. package/dest/state_machine/archiver.js +28 -20
  84. package/dest/state_machine/dummy_p2p_client.d.ts +22 -10
  85. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  86. package/dest/state_machine/dummy_p2p_client.js +38 -8
  87. package/dest/state_machine/global_variable_builder.d.ts +10 -6
  88. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  89. package/dest/state_machine/global_variable_builder.js +8 -5
  90. package/dest/state_machine/index.d.ts +11 -5
  91. package/dest/state_machine/index.d.ts.map +1 -1
  92. package/dest/state_machine/index.js +50 -10
  93. package/dest/state_machine/mock_epoch_cache.d.ts +16 -3
  94. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  95. package/dest/state_machine/mock_epoch_cache.js +29 -2
  96. package/dest/state_machine/synchronizer.d.ts +14 -6
  97. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  98. package/dest/state_machine/synchronizer.js +22 -9
  99. package/dest/txe_session.d.ts +90 -16
  100. package/dest/txe_session.d.ts.map +1 -1
  101. package/dest/txe_session.js +331 -67
  102. package/dest/utils/block_creation.d.ts +2 -2
  103. package/dest/utils/block_creation.d.ts.map +1 -1
  104. package/dest/utils/block_creation.js +2 -2
  105. package/dest/utils/encoding.d.ts +192 -0
  106. package/dest/utils/encoding.d.ts.map +1 -0
  107. package/dest/{util → utils}/encoding.js +7 -2
  108. package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
  109. package/dest/utils/expected_failure_error.d.ts.map +1 -0
  110. package/dest/utils/tx_effect_creation.d.ts +1 -1
  111. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  112. package/dest/utils/tx_effect_creation.js +0 -1
  113. package/dest/{util → utils}/txe_account_store.d.ts +1 -1
  114. package/dest/utils/txe_account_store.d.ts.map +1 -0
  115. package/dest/utils/txe_artifact_resolver.d.ts +37 -0
  116. package/dest/utils/txe_artifact_resolver.d.ts.map +1 -0
  117. package/dest/utils/txe_artifact_resolver.js +161 -0
  118. package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
  119. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
  120. package/dest/utils/txe_public_contract_data_source.js +51 -0
  121. package/dest/worker.bundle.js +3 -0
  122. package/dest/worker.bundle.js.map +7 -0
  123. package/dest/worker.d.ts +2 -0
  124. package/dest/worker.d.ts.map +1 -0
  125. package/dest/worker.js +92 -0
  126. package/package.json +38 -21
  127. package/src/bin/check_txe_oracle_version.ts +67 -0
  128. package/src/bin/index.ts +11 -2
  129. package/src/bin/oracle_test_server.ts +51 -0
  130. package/src/constants.ts +11 -1
  131. package/src/dispatcher_pool.ts +317 -0
  132. package/src/index.ts +99 -190
  133. package/src/msgpackr_fr_extension.ts +23 -0
  134. package/src/oracle/interfaces.ts +75 -35
  135. package/src/oracle/tagging_secret_strategy.ts +25 -0
  136. package/src/oracle/test-resolver/default_fixtures.ts +271 -0
  137. package/src/oracle/test-resolver/index.ts +44 -0
  138. package/src/oracle/test-resolver/resolver.ts +245 -0
  139. package/src/oracle/txe_oracle_public_context.ts +74 -12
  140. package/src/oracle/txe_oracle_registry.ts +556 -0
  141. package/src/oracle/txe_oracle_top_level_context.ts +411 -137
  142. package/src/oracle/txe_oracle_version.ts +17 -0
  143. package/src/oracle/txe_private_execution_oracle.ts +30 -0
  144. package/src/rpc_server.ts +87 -0
  145. package/src/rpc_translator.ts +1116 -1006
  146. package/src/state_machine/archiver.ts +41 -20
  147. package/src/state_machine/dummy_p2p_client.ts +62 -17
  148. package/src/state_machine/global_variable_builder.ts +12 -11
  149. package/src/state_machine/index.ts +63 -27
  150. package/src/state_machine/mock_epoch_cache.ts +38 -3
  151. package/src/state_machine/synchronizer.ts +31 -10
  152. package/src/txe_session.ts +570 -77
  153. package/src/utils/block_creation.ts +2 -1
  154. package/src/{util → utils}/encoding.ts +8 -2
  155. package/src/utils/tx_effect_creation.ts +0 -2
  156. package/src/utils/txe_artifact_resolver.ts +217 -0
  157. package/src/utils/txe_public_contract_data_source.ts +60 -0
  158. package/src/worker.ts +98 -0
  159. package/dest/util/encoding.d.ts +0 -720
  160. package/dest/util/encoding.d.ts.map +0 -1
  161. package/dest/util/expected_failure_error.d.ts.map +0 -1
  162. package/dest/util/txe_account_store.d.ts.map +0 -1
  163. package/dest/util/txe_contract_store.d.ts +0 -12
  164. package/dest/util/txe_contract_store.d.ts.map +0 -1
  165. package/dest/util/txe_contract_store.js +0 -22
  166. package/dest/util/txe_public_contract_data_source.d.ts +0 -21
  167. package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
  168. package/dest/util/txe_public_contract_data_source.js +0 -67
  169. package/src/util/txe_contract_store.ts +0 -36
  170. package/src/util/txe_public_contract_data_source.ts +0 -86
  171. /package/dest/{util → utils}/expected_failure_error.js +0 -0
  172. /package/dest/{util → utils}/txe_account_store.js +0 -0
  173. /package/src/{util → utils}/expected_failure_error.ts +0 -0
  174. /package/src/{util → utils}/txe_account_store.ts +0 -0
@@ -1,29 +1,98 @@
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
+ function _ts_add_disposable_resource(env, value, async) {
2
+ if (value !== null && value !== void 0) {
3
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
4
+ var dispose, inner;
5
+ if (async) {
6
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
7
+ dispose = value[Symbol.asyncDispose];
8
+ }
9
+ if (dispose === void 0) {
10
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
11
+ dispose = value[Symbol.dispose];
12
+ if (async) inner = dispose;
13
+ }
14
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
15
+ if (inner) dispose = function() {
16
+ try {
17
+ inner.call(this);
18
+ } catch (e) {
19
+ return Promise.reject(e);
20
+ }
21
+ };
22
+ env.stack.push({
23
+ value: value,
24
+ dispose: dispose,
25
+ async: async
26
+ });
27
+ } else if (async) {
28
+ env.stack.push({
29
+ async: true
30
+ });
31
+ }
32
+ return value;
33
+ }
34
+ function _ts_dispose_resources(env) {
35
+ var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
36
+ var e = new Error(message);
37
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
38
+ };
39
+ return (_ts_dispose_resources = function _ts_dispose_resources(env) {
40
+ function fail(e) {
41
+ env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
42
+ env.hasError = true;
43
+ }
44
+ var r, s = 0;
45
+ function next() {
46
+ while(r = env.stack.pop()){
47
+ try {
48
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
49
+ if (r.dispose) {
50
+ var result = r.dispose.call(r.value);
51
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) {
52
+ fail(e);
53
+ return next();
54
+ });
55
+ } else s |= 1;
56
+ } catch (e) {
57
+ fail(e);
58
+ }
59
+ }
60
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
61
+ if (env.hasError) throw env.error;
62
+ }
63
+ return next();
64
+ })(env);
65
+ }
66
+ import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, MAX_PRIVATE_LOGS_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
2
67
  import { BlockNumber } from '@aztec/foundation/branded-types';
3
68
  import { Schnorr } from '@aztec/foundation/crypto/schnorr';
4
69
  import { Fr } from '@aztec/foundation/curves/bn254';
5
70
  import { LogLevels, applyStringFormatting, createLogger } from '@aztec/foundation/log';
6
71
  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';
72
+ import { AnchoredContractData, CapsuleService, FactService, ORACLE_VERSION_MAJOR, composeHooks, enrichPublicSimulationError } from '@aztec/pxe/server';
73
+ import { CONTRACT_INSTANCE, ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache, PrivateExecutionOracle, TransientArrayService, UtilityExecutionOracle, buildACIRCallback, executePrivateFunction, generateSimulatedProvingResult } from '@aztec/pxe/simulator';
9
74
  import { ExecutionError, WASMSimulator, createSimulationError, extractCallStack, resolveAssertionMessageFromError, toACVMWitness, witnessMapToFields } from '@aztec/simulator/client';
10
- import { CppPublicTxSimulator, GuardedMerkleTreeOperations, PublicContractsDB, PublicProcessor } from '@aztec/simulator/server';
75
+ import { GuardedMerkleTreeOperations, PublicContractsDB, PublicProcessor, PublicTxSimulator } from '@aztec/simulator/server';
11
76
  import { FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
12
77
  import { AuthWitness } from '@aztec/stdlib/auth-witness';
13
78
  import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
14
79
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
15
80
  import { computePartialAddress } from '@aztec/stdlib/contract';
16
- import { Gas, GasFees, GasSettings } from '@aztec/stdlib/gas';
81
+ import { Gas, GasFees } from '@aztec/stdlib/gas';
17
82
  import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
18
83
  import { PartialPrivateTailPublicInputsForPublic, PrivateKernelTailCircuitPublicInputs, PrivateToPublicAccumulatedData, PublicCallRequest } from '@aztec/stdlib/kernel';
84
+ import { deriveKeys, hashPublicKey } from '@aztec/stdlib/keys';
85
+ import { AppTaggingSecretKind } from '@aztec/stdlib/logs';
86
+ import { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
19
87
  import { ChonkProof } from '@aztec/stdlib/proofs';
20
88
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
21
89
  import { MerkleTreeId } from '@aztec/stdlib/trees';
22
90
  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';
91
+ import { ForkCheckpoint } from '@aztec/world-state/native';
92
+ import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
26
93
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
94
+ import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
95
+ import { makeResolveTaggingSecretStrategyHook } from './tagging_secret_strategy.js';
27
96
  export class TXEOracleTopLevelContext {
28
97
  stateMachine;
29
98
  contractStore;
@@ -33,18 +102,23 @@ export class TXEOracleTopLevelContext {
33
102
  accountStore;
34
103
  senderTaggingStore;
35
104
  recipientTaggingStore;
36
- senderAddressBookStore;
105
+ taggingSecretSourcesStore;
37
106
  capsuleStore;
107
+ factStore;
38
108
  privateEventStore;
39
- jobId;
40
109
  nextBlockTimestamp;
41
110
  version;
42
111
  chainId;
43
112
  authwits;
113
+ taggingSecretStrategies;
114
+ authorizeAllUtilityCallTargets;
115
+ artifactResolver;
116
+ rootPath;
117
+ packageName;
44
118
  isMisc;
45
119
  isTxe;
46
120
  logger;
47
- constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, jobId, nextBlockTimestamp, version, chainId, authwits){
121
+ constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, taggingSecretSourcesStore, capsuleStore, factStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits, taggingSecretStrategies, authorizeAllUtilityCallTargets, artifactResolver, rootPath, packageName){
48
122
  this.stateMachine = stateMachine;
49
123
  this.contractStore = contractStore;
50
124
  this.noteStore = noteStore;
@@ -53,31 +127,46 @@ export class TXEOracleTopLevelContext {
53
127
  this.accountStore = accountStore;
54
128
  this.senderTaggingStore = senderTaggingStore;
55
129
  this.recipientTaggingStore = recipientTaggingStore;
56
- this.senderAddressBookStore = senderAddressBookStore;
130
+ this.taggingSecretSourcesStore = taggingSecretSourcesStore;
57
131
  this.capsuleStore = capsuleStore;
132
+ this.factStore = factStore;
58
133
  this.privateEventStore = privateEventStore;
59
- this.jobId = jobId;
60
134
  this.nextBlockTimestamp = nextBlockTimestamp;
61
135
  this.version = version;
62
136
  this.chainId = chainId;
63
137
  this.authwits = authwits;
138
+ this.taggingSecretStrategies = taggingSecretStrategies;
139
+ this.authorizeAllUtilityCallTargets = authorizeAllUtilityCallTargets;
140
+ this.artifactResolver = artifactResolver;
141
+ this.rootPath = rootPath;
142
+ this.packageName = packageName;
64
143
  this.isMisc = true;
65
144
  this.isTxe = true;
66
145
  this.logger = createLogger('txe:top_level_context');
67
146
  this.logger.debug('Entering Top Level Context');
68
147
  }
69
- utilityAssertCompatibleOracleVersion(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}'.`);
148
+ contractOracleVersion;
149
+ assertCompatibleOracleVersion(major, minor) {
150
+ if (major !== ORACLE_VERSION_MAJOR) {
151
+ 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.';
152
+ 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
153
  }
154
+ this.contractOracleVersion = {
155
+ major,
156
+ minor
157
+ };
158
+ }
159
+ // Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
160
+ nonOracleFunctionGetContractOracleVersion() {
161
+ return this.contractOracleVersion;
73
162
  }
74
163
  // This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
75
164
  // setup.
76
- utilityGetRandomField() {
165
+ getRandomField() {
77
166
  return Fr.random();
78
167
  }
79
168
  // We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
80
- utilityLog(level, message, fields) {
169
+ log(level, message, _fieldsSize, fields) {
81
170
  if (!LogLevels[level]) {
82
171
  throw new Error(`Invalid log level: ${level}`);
83
172
  }
@@ -87,34 +176,56 @@ export class TXEOracleTopLevelContext {
87
176
  });
88
177
  return Promise.resolve();
89
178
  }
90
- txeGetDefaultAddress() {
179
+ getDefaultAddress() {
91
180
  return DEFAULT_ADDRESS;
92
181
  }
93
- async txeGetNextBlockNumber() {
182
+ async getNextBlockNumber() {
94
183
  return BlockNumber(await this.getLastBlockNumber() + 1);
95
184
  }
96
- txeGetNextBlockTimestamp() {
185
+ getNextBlockTimestamp() {
97
186
  return Promise.resolve(this.nextBlockTimestamp);
98
187
  }
99
- async txeGetLastBlockTimestamp() {
100
- return (await this.stateMachine.node.getBlockHeader('latest')).globalVariables.timestamp;
188
+ async getLastBlockTimestamp() {
189
+ return (await this.stateMachine.node.getBlockData('latest')).header.globalVariables.timestamp;
101
190
  }
102
- async txeGetLastTxEffects() {
191
+ async getLastTxEffects() {
103
192
  const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
104
- const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
193
+ const block = await this.stateMachine.archiver.getBlock({
194
+ number: latestBlockNumber
195
+ });
105
196
  if (block.body.txEffects.length != 1) {
106
197
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
107
198
  throw new Error(`Expected a single transaction in the last block, found ${block.body.txEffects.length}`);
108
199
  }
109
200
  const txEffects = block.body.txEffects[0];
201
+ const privateLogs = txEffects.privateLogs;
202
+ if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
203
+ throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
204
+ }
110
205
  return {
111
206
  txHash: txEffects.txHash,
112
207
  noteHashes: txEffects.noteHashes,
113
- nullifiers: txEffects.nullifiers
208
+ nullifiers: txEffects.nullifiers,
209
+ privateLogs
114
210
  };
115
211
  }
116
- async txeGetPrivateEvents(selector, contractAddress, scope) {
117
- return (await this.privateEventStore.getPrivateEvents(selector, {
212
+ async syncContractNonOracleMethod(contractAddress, scope, jobId) {
213
+ if (contractAddress.equals(DEFAULT_ADDRESS)) {
214
+ this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
215
+ return;
216
+ }
217
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
218
+ await this.stateMachine.contractSyncService.ensureContractSynced(contractAddress, null, async (call, execScopes)=>{
219
+ await this.executeUtilityCall(call, {
220
+ scopes: execScopes,
221
+ jobId
222
+ });
223
+ }, blockHeader, jobId, [
224
+ scope
225
+ ]);
226
+ }
227
+ async getPrivateEvents(selector, contractAddress, scope) {
228
+ const events = (await this.privateEventStore.getPrivateEvents(selector, {
118
229
  contractAddress,
119
230
  scopes: [
120
231
  scope
@@ -122,63 +233,119 @@ export class TXEOracleTopLevelContext {
122
233
  fromBlock: 0,
123
234
  toBlock: await this.getLastBlockNumber() + 1
124
235
  })).map((e)=>e.packedEvent);
236
+ if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
237
+ throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
238
+ }
239
+ if (events.some((e)=>e.length > MAX_PRIVATE_EVENT_LEN)) {
240
+ throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
241
+ }
242
+ return events;
125
243
  }
126
- async txeAdvanceBlocksBy(blocks) {
244
+ async advanceBlocksBy(blocks) {
127
245
  this.logger.debug(`time traveling ${blocks} blocks`);
128
246
  for(let i = 0; i < blocks; i++){
129
247
  await this.mineBlock();
130
248
  }
131
249
  }
132
- txeAdvanceTimestampBy(duration) {
250
+ advanceTimestampBy(duration) {
133
251
  this.logger.debug(`time traveling ${duration} seconds`);
134
252
  this.nextBlockTimestamp += duration;
135
253
  }
136
- async txeDeploy(artifact, instance, secret) {
254
+ deploymentNullifier(address) {
255
+ return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
256
+ }
257
+ async deploy(contractPath, initializer, args, secret, salt, deployer) {
258
+ const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
259
+ rootPath: this.rootPath,
260
+ packageName: this.packageName,
261
+ contractPath,
262
+ initializer,
263
+ args,
264
+ secret,
265
+ salt,
266
+ deployer
267
+ });
137
268
  // Emit deployment nullifier
138
269
  await this.mineBlock({
139
270
  nullifiers: [
140
- await siloNullifier(AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), instance.address.toField())
271
+ await this.deploymentNullifier(instance.address)
141
272
  ]
142
273
  });
143
274
  if (!secret.equals(Fr.ZERO)) {
144
- await this.txeAddAccount(artifact, instance, secret);
275
+ await this.registerContractAndAddAccount(artifact, instance, secret);
145
276
  } else {
146
277
  await this.contractStore.addContractInstance(instance);
147
- await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
278
+ await this.contractStore.addContractArtifact(artifact);
148
279
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
149
280
  }
281
+ return CONTRACT_INSTANCE.serialization.fn(instance).flat();
282
+ }
283
+ /**
284
+ * Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
285
+ */ async mineDeploymentNullifiers(addresses) {
286
+ await this.mineBlock({
287
+ nullifiers: await Promise.all(addresses.map((address)=>this.deploymentNullifier(address)))
288
+ });
289
+ }
290
+ async addAccount(secret) {
291
+ const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
292
+ return this.registerContractAndAddAccount(artifact, instance, secret);
150
293
  }
151
- async txeAddAccount(artifact, instance, secret) {
294
+ async registerContractAndAddAccount(artifact, instance, secret) {
152
295
  const partialAddress = await computePartialAddress(instance);
153
296
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
154
297
  await this.contractStore.addContractInstance(instance);
155
- await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
156
- const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
298
+ await this.contractStore.addContractArtifact(artifact);
299
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
157
300
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
158
301
  await this.addressStore.addCompleteAddress(completeAddress);
159
302
  this.logger.debug(`Created account ${completeAddress.address}`);
160
303
  return completeAddress;
161
304
  }
162
- async txeCreateAccount(secret) {
163
- // This is a foot gun !
164
- const completeAddress = await this.keyStore.addAccount(secret, secret);
305
+ async createAccount(secret, partialAddress) {
306
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
165
307
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
166
308
  await this.addressStore.addCompleteAddress(completeAddress);
167
309
  this.logger.debug(`Created account ${completeAddress.address}`);
168
310
  return completeAddress;
169
311
  }
170
- async txeAddAuthWitness(address, messageHash) {
312
+ async addAuthWitness(address, messageHash) {
171
313
  const account = await this.accountStore.getAccount(address);
172
- const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
314
+ const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
315
+ const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
173
316
  const schnorr = new Schnorr();
174
- const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
175
- const authWitness = new AuthWitness(messageHash, [
176
- ...signature.toBuffer()
177
- ]);
317
+ const signature = await schnorr.constructSignature(messageHash, privateKey);
318
+ const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
178
319
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
179
320
  }
321
+ setTaggingSecretStrategies(unconstrainedStrategy, constrainedStrategy) {
322
+ const apply = (mode, strategy)=>{
323
+ if (strategy.isSome()) {
324
+ this.taggingSecretStrategies.set(mode, strategy.value);
325
+ } else {
326
+ this.taggingSecretStrategies.delete(mode);
327
+ }
328
+ };
329
+ apply(AppTaggingSecretKind.UNCONSTRAINED, unconstrainedStrategy);
330
+ apply(AppTaggingSecretKind.CONSTRAINED, constrainedStrategy);
331
+ }
332
+ setAuthorizeAllUtilityCallTargets(authorizeAll) {
333
+ this.authorizeAllUtilityCallTargets = authorizeAll;
334
+ }
335
+ async sendL1ToL2Message(content, secretHash, sender, recipient) {
336
+ // Messages are appended to the tree, so the next free slot is simply the current tree size.
337
+ const { size } = await this.stateMachine.synchronizer.getCommitted().getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
338
+ const leafIndex = new Fr(size);
339
+ const message = new L1ToL2Message(new L1Actor(sender, this.chainId.toNumber()), new L2Actor(recipient, this.version.toNumber()), content, secretHash, leafIndex);
340
+ await this.mineBlock({
341
+ l1ToL2Messages: [
342
+ message.hash()
343
+ ]
344
+ });
345
+ return leafIndex;
346
+ }
180
347
  async mineBlock(options = {}) {
181
- const blockNumber = await this.txeGetNextBlockNumber();
348
+ const blockNumber = await this.getNextBlockNumber();
182
349
  const txEffect = TxEffect.empty();
183
350
  txEffect.nullifiers = [
184
351
  getSingleTxBlockRequestHash(blockNumber),
@@ -186,7 +353,7 @@ export class TXEOracleTopLevelContext {
186
353
  ];
187
354
  txEffect.txHash = new TxHash(new Fr(blockNumber));
188
355
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
189
- await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
356
+ await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
190
357
  const globals = makeGlobalVariables(undefined, {
191
358
  blockNumber,
192
359
  timestamp: this.nextBlockTimestamp,
@@ -198,270 +365,320 @@ export class TXEOracleTopLevelContext {
198
365
  ]);
199
366
  await forkedWorldTrees.close();
200
367
  this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
201
- await this.stateMachine.handleL2Block(block);
368
+ await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
202
369
  }
203
- async txePrivateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false) {
204
- this.logger.verbose(`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
205
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
206
- if (!artifact) {
207
- 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';
208
- throw new Error(message);
209
- }
210
- // When `from` is the zero address (used when creating a new contract account for example),
211
- // we disable scope filtering by setting effectiveScopes to undefined. This allows these operations
212
- // to proceed without requiring keys registered for the zero address.
213
- const effectiveScopes = from.isZero() ? undefined : [
214
- from
215
- ];
216
- // Sync notes before executing private function to discover notes from previous transactions
217
- const utilityExecutor = async (call, execScopes)=>{
218
- await this.executeUtilityCall(call, execScopes);
370
+ async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, additionalScopes = [], jobId, authorizedUtilityCallTargets, gasSettings) {
371
+ const env = {
372
+ stack: [],
373
+ error: void 0,
374
+ hasError: false
219
375
  };
220
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
221
- await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, this.jobId, effectiveScopes);
222
- const blockNumber = await this.txeGetNextBlockNumber();
223
- const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
224
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
225
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
226
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
227
- const txContext = new TxContext(this.chainId, this.version, gasSettings);
228
- const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
229
- const noteCache = new ExecutionNoteCache(protocolNullifier);
230
- // In production, the account contract sets the min revertible counter before calling the app function.
231
- // Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
232
- // marking all side effects as revertible.
233
- const minRevertibleSideEffectCounter = 1;
234
- await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
235
- const taggingIndexCache = new ExecutionTaggingIndexCache();
236
- const simulator = new WASMSimulator();
237
- const privateExecutionOracle = new PrivateExecutionOracle({
238
- argsHash,
239
- txContext,
240
- callContext,
241
- anchorBlockHeader: blockHeader,
242
- utilityExecutor,
243
- authWitnesses: Array.from(this.authwits.values()),
244
- capsules: [],
245
- executionCache: HashedValuesCache.create([
246
- new HashedValues(args, argsHash)
247
- ]),
248
- noteCache,
249
- taggingIndexCache,
250
- contractStore: this.contractStore,
251
- noteStore: this.noteStore,
252
- keyStore: this.keyStore,
253
- addressStore: this.addressStore,
254
- aztecNode: this.stateMachine.node,
255
- senderTaggingStore: this.senderTaggingStore,
256
- recipientTaggingStore: this.recipientTaggingStore,
257
- senderAddressBookStore: this.senderAddressBookStore,
258
- capsuleStore: this.capsuleStore,
259
- privateEventStore: this.privateEventStore,
260
- contractSyncService: this.stateMachine.contractSyncService,
261
- jobId: this.jobId,
262
- totalPublicCalldataCount: 0,
263
- sideEffectCounter: minRevertibleSideEffectCounter,
264
- scopes: effectiveScopes,
265
- // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
266
- // contract would perform, including setting senderForTags.
267
- senderForTags: from,
268
- simulator
269
- });
270
- // 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.
271
- let result;
272
- let executionResult;
273
376
  try {
274
- executionResult = await executePrivateFunction(simulator, privateExecutionOracle, artifact, targetContractAddress, functionSelector);
275
- const publicCallRequests = collectNested([
377
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
378
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
379
+ this.logger.verbose(`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
380
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
381
+ if (!artifact) {
382
+ 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';
383
+ throw new Error(message);
384
+ }
385
+ const scopes = from === undefined ? additionalScopes : [
386
+ from,
387
+ ...additionalScopes
388
+ ];
389
+ // Sync notes before executing private function to discover notes from previous transactions
390
+ const utilityExecutor = async (call, execScopes)=>{
391
+ await this.executeUtilityCall(call, {
392
+ scopes: execScopes,
393
+ jobId
394
+ });
395
+ };
396
+ await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, scopes);
397
+ const blockNumber = await this.getNextBlockNumber();
398
+ const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
399
+ const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
400
+ const txContext = new TxContext(this.chainId, this.version, gasSettings);
401
+ const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
402
+ const noteCache = new ExecutionNoteCache(protocolNullifier);
403
+ // In production, the account contract sets the min revertible counter before calling the app function.
404
+ // Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
405
+ // marking all side effects as revertible.
406
+ const minRevertibleSideEffectCounter = 1;
407
+ await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
408
+ const taggingIndexCache = new ExecutionTaggingIndexCache();
409
+ const simulator = new WASMSimulator();
410
+ const transientArrayService = new TransientArrayService();
411
+ const privateExecutionOracle = new PrivateExecutionOracle({
412
+ argsHash,
413
+ txContext,
414
+ txRequestSalt: Fr.ZERO,
415
+ callContext,
416
+ anchorBlockHeader: blockHeader,
417
+ utilityExecutor,
418
+ authWitnesses: Array.from(this.authwits.values()),
419
+ capsules: [],
420
+ executionCache: HashedValuesCache.create([
421
+ new HashedValues(args, argsHash)
422
+ ]),
423
+ noteCache,
424
+ taggingIndexCache,
425
+ anchoredContractData,
426
+ noteStore: this.noteStore,
427
+ keyStore: this.keyStore,
428
+ addressStore: this.addressStore,
429
+ aztecNode: this.stateMachine.node,
430
+ senderTaggingStore: this.senderTaggingStore,
431
+ recipientTaggingStore: this.recipientTaggingStore,
432
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
433
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
434
+ factService: new FactService(this.factStore, scopes),
435
+ privateEventStore: this.privateEventStore,
436
+ contractSyncService: this.stateMachine.contractSyncService,
437
+ jobId,
438
+ totalPublicCalldataCount: 0,
439
+ sideEffectCounter: minRevertibleSideEffectCounter,
440
+ scopes,
441
+ // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
442
+ // contract would perform, including setting senderForTags.
443
+ senderForTags: from,
444
+ simulator,
445
+ txResolver: this.stateMachine.txResolver,
446
+ l2TipsStore: this.stateMachine.l2TipsProvider,
447
+ hooks: composeHooks({
448
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(isStaticCall ? 'private view' : 'private', authorizedUtilityCallTargets),
449
+ resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies)
450
+ }),
451
+ transientArrayService
452
+ });
453
+ // 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.
454
+ let result;
455
+ let executionResult;
456
+ try {
457
+ executionResult = await executePrivateFunction(simulator, privateExecutionOracle, artifact, targetContractAddress, functionSelector);
458
+ const publicCallRequests = collectNested([
459
+ executionResult
460
+ ], (r)=>r.publicInputs.publicCallRequests.getActiveItems().map((r)=>r.inner).concat(r.publicInputs.publicTeardownCallRequest.isEmpty() ? [] : [
461
+ r.publicInputs.publicTeardownCallRequest
462
+ ]));
463
+ const publicFunctionsCalldata = await Promise.all(publicCallRequests.map(async (r)=>{
464
+ const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
465
+ return new HashedValues(calldata, r.calldataHash);
466
+ }));
467
+ const nonceGenerator = noteCache.getNonceGenerator();
468
+ result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
469
+ } catch (err) {
470
+ throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
471
+ }
472
+ // According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
473
+ // the nonce generator for the note hashes.
474
+ // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
475
+ const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>anchoredContractData.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
476
+ const globals = makeGlobalVariables();
477
+ globals.blockNumber = blockNumber;
478
+ globals.timestamp = this.nextBlockTimestamp;
479
+ globals.chainId = this.chainId;
480
+ globals.version = this.version;
481
+ globals.gasFees = GasFees.empty();
482
+ const forkedWorldTrees = _ts_add_disposable_resource(env, await this.stateMachine.synchronizer.nativeWorldStateService.fork(), true);
483
+ const bindings = this.logger.getBindings();
484
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings);
485
+ const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
486
+ const config = PublicSimulatorConfig.from({
487
+ skipFeeEnforcement: true,
488
+ collectDebugLogs: true,
489
+ collectHints: false,
490
+ collectStatistics: false,
491
+ collectCallMetadata: true
492
+ });
493
+ // The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
494
+ const forkId = forkedWorldTrees.getRevision().forkId;
495
+ const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new PublicTxSimulator(this.stateMachine.synchronizer.avmSimulator, globals, contractsDB, forkId, config, bindings), new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings));
496
+ const tx = await Tx.create({
497
+ data: publicInputs,
498
+ chonkProof: ChonkProof.empty(),
499
+ contractClassLogFields: [],
500
+ publicFunctionCalldata: result.publicFunctionCalldata
501
+ });
502
+ let checkpoint;
503
+ if (isStaticCall) {
504
+ checkpoint = await ForkCheckpoint.new(forkedWorldTrees);
505
+ }
506
+ const results = await processor.process([
507
+ tx
508
+ ]);
509
+ const [processedTx] = results[0];
510
+ const failedTxs = results[1];
511
+ if (failedTxs.length !== 0) {
512
+ throw new Error(`Public execution has failed: ${failedTxs[0].error}`);
513
+ } else if (!processedTx.revertCode.isOK()) {
514
+ if (processedTx.revertReason) {
515
+ try {
516
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, await this.stateMachine.anchorBlockStore.getBlockHeader(), this.logger);
517
+ // eslint-disable-next-line no-empty
518
+ } catch {}
519
+ throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
520
+ } else {
521
+ throw new Error('Contract execution has reverted');
522
+ }
523
+ }
524
+ // Walk the nested private-call tree and collect every offchain effect the transaction emitted.
525
+ // PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
526
+ // `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
527
+ // we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
528
+ const offchainEffects = collectNested([
276
529
  executionResult
277
- ], (r)=>r.publicInputs.publicCallRequests.getActiveItems().map((r)=>r.inner).concat(r.publicInputs.publicTeardownCallRequest.isEmpty() ? [] : [
278
- r.publicInputs.publicTeardownCallRequest
279
- ]));
280
- const publicFunctionsCalldata = await Promise.all(publicCallRequests.map(async (r)=>{
281
- const calldata = await privateExecutionOracle.privateLoadFromExecutionCache(r.calldataHash);
282
- return new HashedValues(calldata, r.calldataHash);
283
- }));
284
- noteCache.finish();
285
- const nonceGenerator = noteCache.getNonceGenerator();
286
- result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
287
- } catch (err) {
288
- throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
289
- }
290
- // According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
291
- // the nonce generator for the note hashes.
292
- // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
293
- const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>this.contractStore.getDebugFunctionName(addr, sel), minRevertibleSideEffectCounter);
294
- const globals = makeGlobalVariables();
295
- globals.blockNumber = blockNumber;
296
- globals.timestamp = this.nextBlockTimestamp;
297
- globals.chainId = this.chainId;
298
- globals.version = this.version;
299
- globals.gasFees = GasFees.empty();
300
- const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
301
- const bindings = this.logger.getBindings();
302
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings);
303
- const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
304
- const config = PublicSimulatorConfig.from({
305
- skipFeeEnforcement: true,
306
- collectDebugLogs: true,
307
- collectHints: false,
308
- collectStatistics: false,
309
- collectCallMetadata: true
310
- });
311
- const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings), new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings));
312
- const tx = await Tx.create({
313
- data: publicInputs,
314
- chonkProof: ChonkProof.empty(),
315
- contractClassLogFields: [],
316
- publicFunctionCalldata: result.publicFunctionCalldata
317
- });
318
- let checkpoint;
319
- if (isStaticCall) {
320
- checkpoint = await ForkCheckpoint.new(forkedWorldTrees);
321
- }
322
- const results = await processor.process([
323
- tx
324
- ]);
325
- const [processedTx] = results[0];
326
- const failedTxs = results[1];
327
- if (failedTxs.length !== 0) {
328
- throw new Error(`Public execution has failed: ${failedTxs[0].error}`);
329
- } else if (!processedTx.revertCode.isOK()) {
330
- if (processedTx.revertReason) {
331
- try {
332
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
333
- // eslint-disable-next-line no-empty
334
- } catch {}
335
- throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
336
- } else {
337
- throw new Error('Contract execution has reverted');
530
+ ], (r)=>r.offchainEffects.map((e)=>e.data));
531
+ if (isStaticCall) {
532
+ await checkpoint.revert();
533
+ return {
534
+ returnValues: executionResult.returnValues ?? [],
535
+ offchainEffects
536
+ };
338
537
  }
538
+ const txEffect = TxEffect.empty();
539
+ txEffect.noteHashes = processedTx.txEffect.noteHashes;
540
+ txEffect.nullifiers = processedTx.txEffect.nullifiers;
541
+ txEffect.privateLogs = processedTx.txEffect.privateLogs;
542
+ txEffect.publicLogs = processedTx.txEffect.publicLogs;
543
+ txEffect.publicDataWrites = processedTx.txEffect.publicDataWrites;
544
+ txEffect.txHash = new TxHash(new Fr(blockNumber));
545
+ const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
546
+ await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
547
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [
548
+ txEffect
549
+ ]);
550
+ await this.stateMachine.handleL2Block(l2Block);
551
+ return {
552
+ returnValues: executionResult.returnValues ?? [],
553
+ offchainEffects
554
+ };
555
+ } catch (e) {
556
+ env.error = e;
557
+ env.hasError = true;
558
+ } finally{
559
+ const result = _ts_dispose_resources(env);
560
+ if (result) await result;
339
561
  }
340
- if (isStaticCall) {
341
- await checkpoint.revert();
342
- await forkedWorldTrees.close();
343
- return executionResult.returnValues ?? [];
344
- }
345
- const txEffect = TxEffect.empty();
346
- txEffect.noteHashes = processedTx.txEffect.noteHashes;
347
- txEffect.nullifiers = processedTx.txEffect.nullifiers;
348
- txEffect.privateLogs = processedTx.txEffect.privateLogs;
349
- txEffect.publicLogs = processedTx.txEffect.publicLogs;
350
- txEffect.publicDataWrites = processedTx.txEffect.publicDataWrites;
351
- txEffect.txHash = new TxHash(new Fr(blockNumber));
352
- const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
353
- await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
354
- const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [
355
- txEffect
356
- ]);
357
- await this.stateMachine.handleL2Block(l2Block);
358
- await forkedWorldTrees.close();
359
- return executionResult.returnValues ?? [];
360
- }
361
- async txePublicCallNewFlow(from, targetContractAddress, calldata, isStaticCall) {
362
- this.logger.verbose(`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
363
- const blockNumber = await this.txeGetNextBlockNumber();
364
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
365
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
366
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
367
- const txContext = new TxContext(this.chainId, this.version, gasSettings);
368
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
369
- const calldataHash = await computeCalldataHash(calldata);
370
- const calldataHashedValues = new HashedValues(calldata, calldataHash);
371
- const globals = makeGlobalVariables();
372
- globals.blockNumber = blockNumber;
373
- globals.timestamp = this.nextBlockTimestamp;
374
- globals.chainId = this.chainId;
375
- globals.version = this.version;
376
- globals.gasFees = GasFees.empty();
377
- const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
378
- const bindings2 = this.logger.getBindings();
379
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings2);
380
- const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
381
- const config = PublicSimulatorConfig.from({
382
- skipFeeEnforcement: true,
383
- collectDebugLogs: true,
384
- collectHints: false,
385
- collectStatistics: false,
386
- collectCallMetadata: true
387
- });
388
- const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
389
- const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings2));
390
- // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
391
- // kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
392
- // side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
393
- // unique.
394
- const nonRevertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
395
- nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
396
- // The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
397
- // may require producing reverts.
398
- const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
399
- revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from, targetContractAddress, isStaticCall, calldataHash);
400
- const inputsForPublic = new PartialPrivateTailPublicInputsForPublic(nonRevertibleAccumulatedData, revertibleAccumulatedData, PublicCallRequest.empty());
401
- const constantData = new TxConstantData(anchorBlockHeader, txContext, Fr.zero(), Fr.zero());
402
- const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*includeByTimestamp=*/ 0n, inputsForPublic, undefined);
403
- const tx = await Tx.create({
404
- data: txData,
405
- chonkProof: ChonkProof.empty(),
406
- contractClassLogFields: [],
407
- publicFunctionCalldata: [
408
- calldataHashedValues
409
- ]
410
- });
411
- let checkpoint;
412
- if (isStaticCall) {
413
- checkpoint = await ForkCheckpoint.new(forkedWorldTrees);
414
- }
415
- const results = await processor.process([
416
- tx
417
- ]);
418
- const [processedTx] = results[0];
419
- const failedTxs = results[1];
420
- if (failedTxs.length !== 0) {
421
- throw new Error(`Public execution has failed: ${failedTxs[0].error}`);
422
- } else if (!processedTx.revertCode.isOK()) {
423
- if (processedTx.revertReason) {
424
- try {
425
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
426
- // eslint-disable-next-line no-empty
427
- } catch {}
428
- throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
429
- } else {
430
- throw new Error('Contract execution has reverted');
562
+ }
563
+ async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall, gasSettings) {
564
+ const env = {
565
+ stack: [],
566
+ error: void 0,
567
+ hasError: false
568
+ };
569
+ try {
570
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
571
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
572
+ this.logger.verbose(`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
573
+ const blockNumber = await this.getNextBlockNumber();
574
+ const txContext = new TxContext(this.chainId, this.version, gasSettings);
575
+ const calldataHash = await computeCalldataHash(calldata);
576
+ const calldataHashedValues = new HashedValues(calldata, calldataHash);
577
+ const globals = makeGlobalVariables();
578
+ globals.blockNumber = blockNumber;
579
+ globals.timestamp = this.nextBlockTimestamp;
580
+ globals.chainId = this.chainId;
581
+ globals.version = this.version;
582
+ globals.gasFees = GasFees.empty();
583
+ const forkedWorldTrees = _ts_add_disposable_resource(env, await this.stateMachine.synchronizer.nativeWorldStateService.fork(), true);
584
+ const bindings2 = this.logger.getBindings();
585
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings2);
586
+ const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
587
+ const config = PublicSimulatorConfig.from({
588
+ skipFeeEnforcement: true,
589
+ collectDebugLogs: true,
590
+ collectHints: false,
591
+ collectStatistics: false,
592
+ collectCallMetadata: true
593
+ });
594
+ // The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
595
+ const forkId2 = forkedWorldTrees.getRevision().forkId;
596
+ const simulator = new PublicTxSimulator(this.stateMachine.synchronizer.avmSimulator, globals, contractsDB, forkId2, config, bindings2);
597
+ const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings2));
598
+ // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
599
+ // kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
600
+ // side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
601
+ // unique.
602
+ const nonRevertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
603
+ nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
604
+ // The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
605
+ // may require producing reverts.
606
+ const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
607
+ revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from ?? AztecAddress.NULL_MSG_SENDER, targetContractAddress, isStaticCall, calldataHash);
608
+ const inputsForPublic = new PartialPrivateTailPublicInputsForPublic(nonRevertibleAccumulatedData, revertibleAccumulatedData, PublicCallRequest.empty());
609
+ const constantData = new TxConstantData(anchorBlockHeader, txContext, Fr.zero(), Fr.zero());
610
+ const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*expirationTimestamp=*/ 0n, inputsForPublic, undefined);
611
+ const tx = await Tx.create({
612
+ data: txData,
613
+ chonkProof: ChonkProof.empty(),
614
+ contractClassLogFields: [],
615
+ publicFunctionCalldata: [
616
+ calldataHashedValues
617
+ ]
618
+ });
619
+ let checkpoint;
620
+ if (isStaticCall) {
621
+ checkpoint = await ForkCheckpoint.new(forkedWorldTrees);
431
622
  }
432
- }
433
- const returnValues = results[3][0].values;
434
- if (isStaticCall) {
435
- await checkpoint.revert();
436
- await forkedWorldTrees.close();
623
+ const results = await processor.process([
624
+ tx
625
+ ]);
626
+ const [processedTx] = results[0];
627
+ const failedTxs = results[1];
628
+ if (failedTxs.length !== 0) {
629
+ throw new Error(`Public execution has failed: ${failedTxs[0].error}`);
630
+ } else if (!processedTx.revertCode.isOK()) {
631
+ if (processedTx.revertReason) {
632
+ try {
633
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader, this.logger);
634
+ // eslint-disable-next-line no-empty
635
+ } catch {}
636
+ throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
637
+ } else {
638
+ throw new Error('Contract execution has reverted');
639
+ }
640
+ }
641
+ const returnValues = results[3][0].values;
642
+ if (isStaticCall) {
643
+ await checkpoint.revert();
644
+ return returnValues ?? [];
645
+ }
646
+ const txEffect = TxEffect.empty();
647
+ txEffect.noteHashes = processedTx.txEffect.noteHashes;
648
+ txEffect.nullifiers = processedTx.txEffect.nullifiers;
649
+ txEffect.privateLogs = processedTx.txEffect.privateLogs;
650
+ txEffect.publicLogs = processedTx.txEffect.publicLogs;
651
+ txEffect.publicDataWrites = processedTx.txEffect.publicDataWrites;
652
+ txEffect.txHash = new TxHash(new Fr(blockNumber));
653
+ const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
654
+ await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
655
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [
656
+ txEffect
657
+ ]);
658
+ await this.stateMachine.handleL2Block(l2Block);
437
659
  return returnValues ?? [];
660
+ } catch (e) {
661
+ env.error = e;
662
+ env.hasError = true;
663
+ } finally{
664
+ const result = _ts_dispose_resources(env);
665
+ if (result) await result;
438
666
  }
439
- const txEffect = TxEffect.empty();
440
- txEffect.noteHashes = processedTx.txEffect.noteHashes;
441
- txEffect.nullifiers = processedTx.txEffect.nullifiers;
442
- txEffect.privateLogs = processedTx.txEffect.privateLogs;
443
- txEffect.publicLogs = processedTx.txEffect.publicLogs;
444
- txEffect.publicDataWrites = processedTx.txEffect.publicDataWrites;
445
- txEffect.txHash = new TxHash(new Fr(blockNumber));
446
- const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
447
- await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
448
- const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [
449
- txEffect
450
- ]);
451
- await this.stateMachine.handleL2Block(l2Block);
452
- await forkedWorldTrees.close();
453
- return returnValues ?? [];
454
667
  }
455
- async txeSimulateUtilityFunction(targetContractAddress, functionSelector, args) {
456
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
668
+ async executeUtilityFunction(from, targetContractAddress, functionSelector, args, jobId, authorizedUtilityCallTargets) {
669
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
670
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
671
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
457
672
  if (!artifact) {
458
673
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
459
674
  }
460
675
  // Sync notes before executing utility function to discover notes from previous transactions
461
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
462
676
  await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, async (call, execScopes)=>{
463
- await this.executeUtilityCall(call, execScopes);
464
- }, blockHeader, this.jobId, undefined);
677
+ await this.executeUtilityCall(call, {
678
+ scopes: execScopes,
679
+ jobId
680
+ });
681
+ }, blockHeader, jobId, await this.keyStore.getAccounts());
465
682
  const call = FunctionCall.from({
466
683
  name: artifact.name,
467
684
  to: targetContractAddress,
@@ -472,10 +689,20 @@ export class TXEOracleTopLevelContext {
472
689
  args,
473
690
  returnTypes: []
474
691
  });
475
- return this.executeUtilityCall(call, undefined);
692
+ return this.executeUtilityCall(call, {
693
+ from,
694
+ scopes: await this.keyStore.getAccounts(),
695
+ jobId,
696
+ authorizedUtilityCallTargets
697
+ });
476
698
  }
477
- async executeUtilityCall(call, scopes) {
478
- const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
699
+ async executeUtilityCall(call, { from = AztecAddress.NULL_MSG_SENDER, scopes, jobId, authorizedUtilityCallTargets = [] }) {
700
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
701
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
702
+ const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
703
+ if (!entryPointArtifact) {
704
+ throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
705
+ }
479
706
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
480
707
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
481
708
  }
@@ -484,25 +711,47 @@ export class TXEOracleTopLevelContext {
484
711
  selector: call.selector
485
712
  });
486
713
  try {
487
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
714
+ const simulator = new WASMSimulator();
715
+ const utilityExecutor = async (syncCall, execScopes)=>{
716
+ await this.executeUtilityCall(syncCall, {
717
+ scopes: execScopes,
718
+ jobId
719
+ });
720
+ };
488
721
  const oracle = new UtilityExecutionOracle({
489
- contractAddress: call.to,
722
+ callContext: CallContext.from({
723
+ msgSender: from,
724
+ contractAddress: call.to,
725
+ functionSelector: call.selector,
726
+ isStaticCall: true
727
+ }),
490
728
  authWitnesses: [],
491
729
  capsules: [],
492
730
  anchorBlockHeader,
493
- contractStore: this.contractStore,
731
+ anchoredContractData,
494
732
  noteStore: this.noteStore,
495
733
  keyStore: this.keyStore,
496
734
  addressStore: this.addressStore,
497
735
  aztecNode: this.stateMachine.node,
498
736
  recipientTaggingStore: this.recipientTaggingStore,
499
- senderAddressBookStore: this.senderAddressBookStore,
500
- capsuleStore: this.capsuleStore,
737
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
738
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
739
+ factService: new FactService(this.factStore, scopes),
501
740
  privateEventStore: this.privateEventStore,
502
- jobId: this.jobId,
503
- scopes
741
+ txResolver: this.stateMachine.txResolver,
742
+ contractSyncService: this.stateMachine.contractSyncService,
743
+ l2TipsStore: this.stateMachine.l2TipsProvider,
744
+ jobId,
745
+ scopes,
746
+ simulator,
747
+ hooks: composeHooks({
748
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets)
749
+ }),
750
+ utilityExecutor,
751
+ // Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
752
+ transientArrayService: new TransientArrayService()
504
753
  });
505
- const acirExecutionResult = await new WASMSimulator().executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback()).catch((err)=>{
754
+ const acirExecutionResult = await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle)).catch((err)=>{
506
755
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
507
756
  throw new ExecutionError(err.message, {
508
757
  contractAddress: call.to,
@@ -511,21 +760,41 @@ export class TXEOracleTopLevelContext {
511
760
  cause: err
512
761
  });
513
762
  });
514
- this.logger.verbose(`Utility simulation for ${call.to}.${call.selector} completed`);
763
+ this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
515
764
  return witnessMapToFields(acirExecutionResult.returnWitness);
516
765
  } catch (err) {
517
- throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility simulation'));
766
+ throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
518
767
  }
519
768
  }
520
769
  close() {
521
770
  this.logger.debug('Exiting Top Level Context');
522
- return [
523
- this.nextBlockTimestamp,
524
- this.authwits
525
- ];
771
+ return {
772
+ nextBlockTimestamp: this.nextBlockTimestamp,
773
+ authwits: this.authwits,
774
+ taggingSecretStrategies: this.taggingSecretStrategies,
775
+ authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets
776
+ };
526
777
  }
527
778
  async getLastBlockNumber() {
528
- const header = await this.stateMachine.node.getBlockHeader('latest');
529
- return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
779
+ const block = await this.stateMachine.node.getBlock('latest');
780
+ return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
781
+ }
782
+ buildAuthorizeUtilityCallHook(callerContext, authorizedTargets) {
783
+ if (this.authorizeAllUtilityCallTargets) {
784
+ return authorizeAllUtilityCallsHook;
785
+ }
786
+ if (authorizedTargets.length === 0) {
787
+ return undefined;
788
+ }
789
+ return (req)=>Promise.resolve({
790
+ authorized: req.callerContext === callerContext && authorizedTargets.some((t)=>t.equals(req.target))
791
+ });
530
792
  }
531
793
  }
794
+ /**
795
+ * An `authorizeUtilityCall` hook that authorizes every cross-contract utility call.
796
+ *
797
+ * Backs the `aztec_txe_setAuthorizeAllUtilityCallTargets` oracle.
798
+ */ export const authorizeAllUtilityCallsHook = ()=>Promise.resolve({
799
+ authorized: true
800
+ });