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

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