@aztec/txe 0.0.1-commit.2ed92850 → 0.0.1-commit.3100065

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-FSRZIMX6.js +3 -0
  2. package/dest/AuthRegistry-FSRZIMX6.js.map +7 -0
  3. package/dest/ContractClassRegistry-N6NA3SFA.js +3 -0
  4. package/dest/ContractClassRegistry-N6NA3SFA.js.map +7 -0
  5. package/dest/ContractInstanceRegistry-NADDSLGL.js +3 -0
  6. package/dest/ContractInstanceRegistry-NADDSLGL.js.map +7 -0
  7. package/dest/FeeJuice-QBH5JWJV.js +3 -0
  8. package/dest/FeeJuice-QBH5JWJV.js.map +7 -0
  9. package/dest/HandshakeRegistry-KKUEU7XW.js +3 -0
  10. package/dest/HandshakeRegistry-KKUEU7XW.js.map +7 -0
  11. package/dest/MultiCallEntrypoint-TGICA67H.js +3 -0
  12. package/dest/MultiCallEntrypoint-TGICA67H.js.map +7 -0
  13. package/dest/SchnorrAccount-J5T6OKR3.js +3 -0
  14. package/dest/SchnorrAccount-J5T6OKR3.js.map +7 -0
  15. package/dest/SchnorrInitializerlessAccount-OOES6Q4F.js +3 -0
  16. package/dest/SchnorrInitializerlessAccount-OOES6Q4F.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 +61 -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-BJVAAXNA.js +3 -0
  26. package/dest/chunk-BJVAAXNA.js.map +7 -0
  27. package/dest/chunk-PDOEF22H.js +304 -0
  28. package/dest/chunk-PDOEF22H.js.map +7 -0
  29. package/dest/chunk-YP4ODNMQ.js +268 -0
  30. package/dest/chunk-YP4ODNMQ.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 +39883 -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 +65 -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 +9 -0
  50. package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
  51. package/dest/oracle/test-resolver/default_fixtures.js +207 -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 +63 -16
  61. package/dest/oracle/txe_oracle_registry.d.ts +170 -0
  62. package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
  63. package/dest/oracle/txe_oracle_registry.js +749 -0
  64. package/dest/oracle/txe_oracle_top_level_context.d.ts +56 -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 +330 -103
  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 +113 -228
  77. package/dest/rpc_translator.d.ts.map +1 -1
  78. package/dest/rpc_translator.js +885 -613
  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 +30 -20
  84. package/dest/state_machine/dummy_p2p_client.d.ts +29 -16
  85. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  86. package/dest/state_machine/dummy_p2p_client.js +53 -20
  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 +13 -7
  91. package/dest/state_machine/index.d.ts.map +1 -1
  92. package/dest/state_machine/index.js +60 -15
  93. package/dest/state_machine/mock_epoch_cache.d.ts +18 -3
  94. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  95. package/dest/state_machine/mock_epoch_cache.js +33 -2
  96. package/dest/state_machine/synchronizer.d.ts +9 -6
  97. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  98. package/dest/state_machine/synchronizer.js +10 -6
  99. package/dest/txe_session.d.ts +89 -16
  100. package/dest/txe_session.d.ts.map +1 -1
  101. package/dest/txe_session.js +363 -56
  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 +5 -3
  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 +70 -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 +71 -35
  135. package/src/oracle/tagging_secret_strategy.ts +25 -0
  136. package/src/oracle/test-resolver/default_fixtures.ts +282 -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 +76 -16
  140. package/src/oracle/txe_oracle_registry.ts +539 -0
  141. package/src/oracle/txe_oracle_top_level_context.ts +440 -168
  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 +1098 -988
  146. package/src/state_machine/archiver.ts +43 -20
  147. package/src/state_machine/dummy_p2p_client.ts +83 -32
  148. package/src/state_machine/global_variable_builder.ts +12 -11
  149. package/src/state_machine/index.ts +84 -33
  150. package/src/state_machine/mock_epoch_cache.ts +43 -3
  151. package/src/state_machine/synchronizer.ts +13 -7
  152. package/src/txe_session.ts +603 -128
  153. package/src/utils/block_creation.ts +5 -2
  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,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, syncState } 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,22 @@ 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
+ artifactResolver;
50
+ rootPath;
51
+ packageName;
44
52
  isMisc;
45
53
  isTxe;
46
54
  logger;
47
- constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, jobId, nextBlockTimestamp, version, chainId, authwits){
55
+ constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, taggingSecretSourcesStore, capsuleStore, factStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits, taggingSecretStrategies, artifactResolver, rootPath, packageName){
48
56
  this.stateMachine = stateMachine;
49
57
  this.contractStore = contractStore;
50
58
  this.noteStore = noteStore;
@@ -53,67 +61,104 @@ export class TXEOracleTopLevelContext {
53
61
  this.accountStore = accountStore;
54
62
  this.senderTaggingStore = senderTaggingStore;
55
63
  this.recipientTaggingStore = recipientTaggingStore;
56
- this.senderAddressBookStore = senderAddressBookStore;
64
+ this.taggingSecretSourcesStore = taggingSecretSourcesStore;
57
65
  this.capsuleStore = capsuleStore;
66
+ this.factStore = factStore;
58
67
  this.privateEventStore = privateEventStore;
59
- this.jobId = jobId;
60
68
  this.nextBlockTimestamp = nextBlockTimestamp;
61
69
  this.version = version;
62
70
  this.chainId = chainId;
63
71
  this.authwits = authwits;
72
+ this.taggingSecretStrategies = taggingSecretStrategies;
73
+ this.artifactResolver = artifactResolver;
74
+ this.rootPath = rootPath;
75
+ this.packageName = packageName;
64
76
  this.isMisc = true;
65
77
  this.isTxe = true;
66
78
  this.logger = createLogger('txe:top_level_context');
67
79
  this.logger.debug('Entering Top Level Context');
68
80
  }
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}'.`);
81
+ contractOracleVersion;
82
+ assertCompatibleOracleVersion(major, minor) {
83
+ if (major !== ORACLE_VERSION_MAJOR) {
84
+ 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.';
85
+ 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
86
  }
87
+ this.contractOracleVersion = {
88
+ major,
89
+ minor
90
+ };
91
+ }
92
+ // Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
93
+ nonOracleFunctionGetContractOracleVersion() {
94
+ return this.contractOracleVersion;
73
95
  }
74
96
  // This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
75
97
  // setup.
76
- utilityGetRandomField() {
98
+ getRandomField() {
77
99
  return Fr.random();
78
100
  }
79
101
  // 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) {
102
+ log(level, message, _fieldsSize, fields) {
81
103
  if (!LogLevels[level]) {
82
- throw new Error(`Invalid debug log level: ${level}`);
104
+ throw new Error(`Invalid log level: ${level}`);
83
105
  }
84
106
  const levelName = LogLevels[level];
85
107
  this.logger[levelName](`${applyStringFormatting(message, fields)}`, {
86
108
  module: `${this.logger.module}:debug_log`
87
109
  });
110
+ return Promise.resolve();
88
111
  }
89
- txeGetDefaultAddress() {
112
+ getDefaultAddress() {
90
113
  return DEFAULT_ADDRESS;
91
114
  }
92
- async txeGetNextBlockNumber() {
115
+ async getNextBlockNumber() {
93
116
  return BlockNumber(await this.getLastBlockNumber() + 1);
94
117
  }
95
- txeGetNextBlockTimestamp() {
118
+ getNextBlockTimestamp() {
96
119
  return Promise.resolve(this.nextBlockTimestamp);
97
120
  }
98
- async txeGetLastBlockTimestamp() {
99
- return (await this.stateMachine.node.getBlockHeader('latest')).globalVariables.timestamp;
121
+ async getLastBlockTimestamp() {
122
+ return (await this.stateMachine.node.getBlockData('latest')).header.globalVariables.timestamp;
100
123
  }
101
- async txeGetLastTxEffects() {
124
+ async getLastTxEffects() {
102
125
  const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
103
- const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
126
+ const block = await this.stateMachine.archiver.getBlock({
127
+ number: latestBlockNumber
128
+ });
104
129
  if (block.body.txEffects.length != 1) {
105
130
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
106
131
  throw new Error(`Expected a single transaction in the last block, found ${block.body.txEffects.length}`);
107
132
  }
108
133
  const txEffects = block.body.txEffects[0];
134
+ const privateLogs = txEffects.privateLogs;
135
+ if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
136
+ throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
137
+ }
109
138
  return {
110
139
  txHash: txEffects.txHash,
111
140
  noteHashes: txEffects.noteHashes,
112
- nullifiers: txEffects.nullifiers
141
+ nullifiers: txEffects.nullifiers,
142
+ privateLogs
113
143
  };
114
144
  }
115
- async txeGetPrivateEvents(selector, contractAddress, scope) {
116
- return (await this.privateEventStore.getPrivateEvents(selector, {
145
+ async syncContractNonOracleMethod(contractAddress, scope, jobId) {
146
+ if (contractAddress.equals(DEFAULT_ADDRESS)) {
147
+ this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
148
+ return;
149
+ }
150
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
151
+ await this.stateMachine.contractSyncService.ensureContractSynced(contractAddress, null, async (call, execScopes)=>{
152
+ await this.executeUtilityCall(call, {
153
+ scopes: execScopes,
154
+ jobId
155
+ });
156
+ }, blockHeader, jobId, [
157
+ scope
158
+ ]);
159
+ }
160
+ async getPrivateEvents(selector, contractAddress, scope) {
161
+ const events = (await this.privateEventStore.getPrivateEvents(selector, {
117
162
  contractAddress,
118
163
  scopes: [
119
164
  scope
@@ -121,63 +166,117 @@ export class TXEOracleTopLevelContext {
121
166
  fromBlock: 0,
122
167
  toBlock: await this.getLastBlockNumber() + 1
123
168
  })).map((e)=>e.packedEvent);
169
+ if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
170
+ throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
171
+ }
172
+ if (events.some((e)=>e.length > MAX_PRIVATE_EVENT_LEN)) {
173
+ throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
174
+ }
175
+ return events;
124
176
  }
125
- async txeAdvanceBlocksBy(blocks) {
177
+ async advanceBlocksBy(blocks) {
126
178
  this.logger.debug(`time traveling ${blocks} blocks`);
127
179
  for(let i = 0; i < blocks; i++){
128
180
  await this.mineBlock();
129
181
  }
130
182
  }
131
- txeAdvanceTimestampBy(duration) {
183
+ advanceTimestampBy(duration) {
132
184
  this.logger.debug(`time traveling ${duration} seconds`);
133
185
  this.nextBlockTimestamp += duration;
134
186
  }
135
- async txeDeploy(artifact, instance, secret) {
187
+ deploymentNullifier(address) {
188
+ return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
189
+ }
190
+ async deploy(contractPath, initializer, args, secret, salt, deployer) {
191
+ const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
192
+ rootPath: this.rootPath,
193
+ packageName: this.packageName,
194
+ contractPath,
195
+ initializer,
196
+ args,
197
+ secret,
198
+ salt,
199
+ deployer
200
+ });
136
201
  // Emit deployment nullifier
137
202
  await this.mineBlock({
138
203
  nullifiers: [
139
- await siloNullifier(AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), instance.address.toField())
204
+ await this.deploymentNullifier(instance.address)
140
205
  ]
141
206
  });
142
207
  if (!secret.equals(Fr.ZERO)) {
143
- await this.txeAddAccount(artifact, instance, secret);
208
+ await this.registerContractAndAddAccount(artifact, instance, secret);
144
209
  } else {
145
210
  await this.contractStore.addContractInstance(instance);
146
- await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
211
+ await this.contractStore.addContractArtifact(artifact);
147
212
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
148
213
  }
214
+ return CONTRACT_INSTANCE.serialization.fn(instance).flat();
215
+ }
216
+ /**
217
+ * Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
218
+ */ async mineDeploymentNullifiers(addresses) {
219
+ await this.mineBlock({
220
+ nullifiers: await Promise.all(addresses.map((address)=>this.deploymentNullifier(address)))
221
+ });
222
+ }
223
+ async addAccount(secret) {
224
+ const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
225
+ return this.registerContractAndAddAccount(artifact, instance, secret);
149
226
  }
150
- async txeAddAccount(artifact, instance, secret) {
227
+ async registerContractAndAddAccount(artifact, instance, secret) {
151
228
  const partialAddress = await computePartialAddress(instance);
152
229
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
153
230
  await this.contractStore.addContractInstance(instance);
154
- await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
155
- const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
231
+ await this.contractStore.addContractArtifact(artifact);
232
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
156
233
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
157
234
  await this.addressStore.addCompleteAddress(completeAddress);
158
235
  this.logger.debug(`Created account ${completeAddress.address}`);
159
236
  return completeAddress;
160
237
  }
161
- async txeCreateAccount(secret) {
238
+ async createAccount(secret) {
162
239
  // This is a foot gun !
163
- const completeAddress = await this.keyStore.addAccount(secret, secret);
240
+ const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), secret);
164
241
  await this.accountStore.setAccount(completeAddress.address, completeAddress);
165
242
  await this.addressStore.addCompleteAddress(completeAddress);
166
243
  this.logger.debug(`Created account ${completeAddress.address}`);
167
244
  return completeAddress;
168
245
  }
169
- async txeAddAuthWitness(address, messageHash) {
246
+ async addAuthWitness(address, messageHash) {
170
247
  const account = await this.accountStore.getAccount(address);
171
- const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
248
+ const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
249
+ const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
172
250
  const schnorr = new Schnorr();
173
- const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
174
- const authWitness = new AuthWitness(messageHash, [
175
- ...signature.toBuffer()
176
- ]);
251
+ const signature = await schnorr.constructSignature(messageHash, privateKey);
252
+ const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
177
253
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
178
254
  }
255
+ setTaggingSecretStrategies(unconstrainedStrategy, constrainedStrategy) {
256
+ const apply = (mode, strategy)=>{
257
+ if (strategy.isSome()) {
258
+ this.taggingSecretStrategies.set(mode, strategy.value);
259
+ } else {
260
+ this.taggingSecretStrategies.delete(mode);
261
+ }
262
+ };
263
+ apply(AppTaggingSecretKind.UNCONSTRAINED, unconstrainedStrategy);
264
+ apply(AppTaggingSecretKind.CONSTRAINED, constrainedStrategy);
265
+ }
266
+ async sendL1ToL2Message(content, secretHash, sender, recipient) {
267
+ // Messages are appended to the tree, so the next free slot is simply the current tree size.
268
+ const { size } = await this.stateMachine.synchronizer.getCommitted().getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
269
+ const leafIndex = new Fr(size);
270
+ const message = new L1ToL2Message(new L1Actor(sender, this.chainId.toNumber()), new L2Actor(recipient, this.version.toNumber()), content, secretHash, leafIndex);
271
+ await this.mineBlock({
272
+ l1ToL2Messages: [
273
+ message.hash()
274
+ ]
275
+ });
276
+ return leafIndex;
277
+ }
179
278
  async mineBlock(options = {}) {
180
- const blockNumber = await this.txeGetNextBlockNumber();
279
+ const blockNumber = await this.getNextBlockNumber();
181
280
  const txEffect = TxEffect.empty();
182
281
  txEffect.nullifiers = [
183
282
  getSingleTxBlockRequestHash(blockNumber),
@@ -185,7 +284,7 @@ export class TXEOracleTopLevelContext {
185
284
  ];
186
285
  txEffect.txHash = new TxHash(new Fr(blockNumber));
187
286
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
188
- await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
287
+ await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
189
288
  const globals = makeGlobalVariables(undefined, {
190
289
  blockNumber,
191
290
  timestamp: this.nextBlockTimestamp,
@@ -197,27 +296,33 @@ export class TXEOracleTopLevelContext {
197
296
  ]);
198
297
  await forkedWorldTrees.close();
199
298
  this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
200
- await this.stateMachine.handleL2Block(block);
299
+ await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
201
300
  }
202
- async txePrivateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false) {
203
- this.logger.verbose(`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
204
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
301
+ async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, additionalScopes = [], jobId, authorizedUtilityCallTargets, gasSettings) {
302
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
303
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
304
+ this.logger.verbose(`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
305
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
205
306
  if (!artifact) {
206
307
  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';
207
308
  throw new Error(message);
208
309
  }
310
+ const scopes = from === undefined ? additionalScopes : [
311
+ from,
312
+ ...additionalScopes
313
+ ];
209
314
  // Sync notes before executing private function to discover notes from previous transactions
210
- const utilityExecutor = async (call)=>{
211
- await this.executeUtilityCall(call);
315
+ const utilityExecutor = async (call, execScopes)=>{
316
+ await this.executeUtilityCall(call, {
317
+ scopes: execScopes,
318
+ jobId
319
+ });
212
320
  };
213
- await syncState(targetContractAddress, this.contractStore, functionSelector, utilityExecutor);
214
- const blockNumber = await this.txeGetNextBlockNumber();
215
- const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
216
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
217
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
218
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
321
+ await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, scopes);
322
+ const blockNumber = await this.getNextBlockNumber();
323
+ const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
324
+ const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
219
325
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
220
- const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
221
326
  const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
222
327
  const noteCache = new ExecutionNoteCache(protocolNullifier);
223
328
  // In production, the account contract sets the min revertible counter before calling the app function.
@@ -227,12 +332,50 @@ export class TXEOracleTopLevelContext {
227
332
  await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
228
333
  const taggingIndexCache = new ExecutionTaggingIndexCache();
229
334
  const simulator = new WASMSimulator();
230
- 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([
231
- new HashedValues(args, argsHash)
232
- ]), noteCache, taggingIndexCache, this.contractStore, this.noteStore, this.keyStore, this.addressStore, this.stateMachine.node, this.stateMachine.anchorBlockStore, this.senderTaggingStore, this.recipientTaggingStore, this.senderAddressBookStore, this.capsuleStore, this.privateEventStore, this.jobId, 0, minRevertibleSideEffectCounter, undefined, undefined, /**
233
- * In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
234
- * contract would perform, including setting senderForTags.
235
- */ from, simulator);
335
+ const transientArrayService = new TransientArrayService();
336
+ const privateExecutionOracle = new PrivateExecutionOracle({
337
+ argsHash,
338
+ txContext,
339
+ // The TXE does not run the init kernel's salt binding, so no tx-request salt is in scope.
340
+ txRequestSalt: Fr.ZERO,
341
+ callContext,
342
+ anchorBlockHeader: blockHeader,
343
+ utilityExecutor,
344
+ authWitnesses: Array.from(this.authwits.values()),
345
+ capsules: [],
346
+ executionCache: HashedValuesCache.create([
347
+ new HashedValues(args, argsHash)
348
+ ]),
349
+ noteCache,
350
+ taggingIndexCache,
351
+ anchoredContractData,
352
+ noteStore: this.noteStore,
353
+ keyStore: this.keyStore,
354
+ addressStore: this.addressStore,
355
+ aztecNode: this.stateMachine.node,
356
+ senderTaggingStore: this.senderTaggingStore,
357
+ recipientTaggingStore: this.recipientTaggingStore,
358
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
359
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
360
+ factService: new FactService(this.factStore, scopes),
361
+ privateEventStore: this.privateEventStore,
362
+ contractSyncService: this.stateMachine.contractSyncService,
363
+ jobId,
364
+ totalPublicCalldataCount: 0,
365
+ sideEffectCounter: minRevertibleSideEffectCounter,
366
+ scopes,
367
+ // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
368
+ // contract would perform, including setting senderForTags.
369
+ senderForTags: from,
370
+ simulator,
371
+ txResolver: this.stateMachine.txResolver,
372
+ l2TipsStore: this.stateMachine.l2TipsProvider,
373
+ hooks: composeHooks({
374
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(isStaticCall ? 'private view' : 'private', authorizedUtilityCallTargets),
375
+ resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies)
376
+ }),
377
+ transientArrayService
378
+ });
236
379
  // 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.
237
380
  let result;
238
381
  let executionResult;
@@ -244,10 +387,9 @@ export class TXEOracleTopLevelContext {
244
387
  r.publicInputs.publicTeardownCallRequest
245
388
  ]));
246
389
  const publicFunctionsCalldata = await Promise.all(publicCallRequests.map(async (r)=>{
247
- const calldata = await privateExecutionOracle.privateLoadFromExecutionCache(r.calldataHash);
390
+ const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
248
391
  return new HashedValues(calldata, r.calldataHash);
249
392
  }));
250
- noteCache.finish();
251
393
  const nonceGenerator = noteCache.getNonceGenerator();
252
394
  result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
253
395
  } catch (err) {
@@ -256,7 +398,7 @@ export class TXEOracleTopLevelContext {
256
398
  // According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
257
399
  // the nonce generator for the note hashes.
258
400
  // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
259
- const { publicInputs } = await generateSimulatedProvingResult(result, this.contractStore, minRevertibleSideEffectCounter);
401
+ const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>anchoredContractData.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
260
402
  const globals = makeGlobalVariables();
261
403
  globals.blockNumber = blockNumber;
262
404
  globals.timestamp = this.nextBlockTimestamp;
@@ -264,7 +406,8 @@ export class TXEOracleTopLevelContext {
264
406
  globals.version = this.version;
265
407
  globals.gasFees = GasFees.empty();
266
408
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
267
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
409
+ const bindings = this.logger.getBindings();
410
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings);
268
411
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
269
412
  const config = PublicSimulatorConfig.from({
270
413
  skipFeeEnforcement: true,
@@ -273,7 +416,7 @@ export class TXEOracleTopLevelContext {
273
416
  collectStatistics: false,
274
417
  collectCallMetadata: true
275
418
  });
276
- const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config), new TestDateProvider());
419
+ const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings), new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings));
277
420
  const tx = await Tx.create({
278
421
  data: publicInputs,
279
422
  chonkProof: ChonkProof.empty(),
@@ -294,7 +437,7 @@ export class TXEOracleTopLevelContext {
294
437
  } else if (!processedTx.revertCode.isOK()) {
295
438
  if (processedTx.revertReason) {
296
439
  try {
297
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
440
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, await this.stateMachine.anchorBlockStore.getBlockHeader(), this.logger);
298
441
  // eslint-disable-next-line no-empty
299
442
  } catch {}
300
443
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -302,10 +445,20 @@ export class TXEOracleTopLevelContext {
302
445
  throw new Error('Contract execution has reverted');
303
446
  }
304
447
  }
448
+ // Walk the nested private-call tree and collect every offchain effect the transaction emitted.
449
+ // PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
450
+ // `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
451
+ // we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
452
+ const offchainEffects = collectNested([
453
+ executionResult
454
+ ], (r)=>r.offchainEffects.map((e)=>e.data));
305
455
  if (isStaticCall) {
306
456
  await checkpoint.revert();
307
457
  await forkedWorldTrees.close();
308
- return executionResult.returnValues ?? [];
458
+ return {
459
+ returnValues: executionResult.returnValues ?? [],
460
+ offchainEffects
461
+ };
309
462
  }
310
463
  const txEffect = TxEffect.empty();
311
464
  txEffect.noteHashes = processedTx.txEffect.noteHashes;
@@ -321,16 +474,17 @@ export class TXEOracleTopLevelContext {
321
474
  ]);
322
475
  await this.stateMachine.handleL2Block(l2Block);
323
476
  await forkedWorldTrees.close();
324
- return executionResult.returnValues ?? [];
477
+ return {
478
+ returnValues: executionResult.returnValues ?? [],
479
+ offchainEffects
480
+ };
325
481
  }
326
- async txePublicCallNewFlow(from, targetContractAddress, calldata, isStaticCall) {
327
- this.logger.verbose(`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
328
- const blockNumber = await this.txeGetNextBlockNumber();
329
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
330
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
331
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
332
- const txContext = new TxContext(this.chainId, this.version, gasSettings);
482
+ async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall, gasSettings) {
333
483
  const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
484
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
485
+ this.logger.verbose(`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
486
+ const blockNumber = await this.getNextBlockNumber();
487
+ const txContext = new TxContext(this.chainId, this.version, gasSettings);
334
488
  const calldataHash = await computeCalldataHash(calldata);
335
489
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
336
490
  const globals = makeGlobalVariables();
@@ -340,7 +494,8 @@ export class TXEOracleTopLevelContext {
340
494
  globals.version = this.version;
341
495
  globals.gasFees = GasFees.empty();
342
496
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
343
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
497
+ const bindings2 = this.logger.getBindings();
498
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings2);
344
499
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
345
500
  const config = PublicSimulatorConfig.from({
346
501
  skipFeeEnforcement: true,
@@ -349,8 +504,8 @@ export class TXEOracleTopLevelContext {
349
504
  collectStatistics: false,
350
505
  collectCallMetadata: true
351
506
  });
352
- const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
353
- const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider());
507
+ const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
508
+ const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings2));
354
509
  // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
355
510
  // kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
356
511
  // side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
@@ -360,10 +515,10 @@ export class TXEOracleTopLevelContext {
360
515
  // The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
361
516
  // may require producing reverts.
362
517
  const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
363
- revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from, targetContractAddress, isStaticCall, calldataHash);
518
+ revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from ?? AztecAddress.NULL_MSG_SENDER, targetContractAddress, isStaticCall, calldataHash);
364
519
  const inputsForPublic = new PartialPrivateTailPublicInputsForPublic(nonRevertibleAccumulatedData, revertibleAccumulatedData, PublicCallRequest.empty());
365
520
  const constantData = new TxConstantData(anchorBlockHeader, txContext, Fr.zero(), Fr.zero());
366
- const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*includeByTimestamp=*/ 0n, inputsForPublic, undefined);
521
+ const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*expirationTimestamp=*/ 0n, inputsForPublic, undefined);
367
522
  const tx = await Tx.create({
368
523
  data: txData,
369
524
  chonkProof: ChonkProof.empty(),
@@ -386,7 +541,7 @@ export class TXEOracleTopLevelContext {
386
541
  } else if (!processedTx.revertCode.isOK()) {
387
542
  if (processedTx.revertReason) {
388
543
  try {
389
- await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
544
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader, this.logger);
390
545
  // eslint-disable-next-line no-empty
391
546
  } catch {}
392
547
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -416,20 +571,44 @@ export class TXEOracleTopLevelContext {
416
571
  await forkedWorldTrees.close();
417
572
  return returnValues ?? [];
418
573
  }
419
- async txeSimulateUtilityFunction(targetContractAddress, functionSelector, args) {
420
- const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
574
+ async executeUtilityFunction(from, targetContractAddress, functionSelector, args, jobId, authorizedUtilityCallTargets) {
575
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
576
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
577
+ const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
421
578
  if (!artifact) {
422
579
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
423
580
  }
424
581
  // Sync notes before executing utility function to discover notes from previous transactions
425
- await syncState(targetContractAddress, this.contractStore, functionSelector, async (call)=>{
426
- await this.executeUtilityCall(call);
582
+ await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, async (call, execScopes)=>{
583
+ await this.executeUtilityCall(call, {
584
+ scopes: execScopes,
585
+ jobId
586
+ });
587
+ }, blockHeader, jobId, await this.keyStore.getAccounts());
588
+ const call = FunctionCall.from({
589
+ name: artifact.name,
590
+ to: targetContractAddress,
591
+ selector: functionSelector,
592
+ type: FunctionType.UTILITY,
593
+ hideMsgSender: false,
594
+ isStatic: false,
595
+ args,
596
+ returnTypes: []
597
+ });
598
+ return this.executeUtilityCall(call, {
599
+ from,
600
+ scopes: await this.keyStore.getAccounts(),
601
+ jobId,
602
+ authorizedUtilityCallTargets
427
603
  });
428
- const call = new FunctionCall(artifact.name, targetContractAddress, functionSelector, FunctionType.UTILITY, false, false, args, []);
429
- return this.executeUtilityCall(call);
430
604
  }
431
- async executeUtilityCall(call) {
432
- const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
605
+ async executeUtilityCall(call, { from = AztecAddress.NULL_MSG_SENDER, scopes, jobId, authorizedUtilityCallTargets = [] }) {
606
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
607
+ const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
608
+ const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
609
+ if (!entryPointArtifact) {
610
+ throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
611
+ }
433
612
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
434
613
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
435
614
  }
@@ -438,9 +617,48 @@ export class TXEOracleTopLevelContext {
438
617
  selector: call.selector
439
618
  });
440
619
  try {
441
- const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
442
- const oracle = new UtilityExecutionOracle(call.to, [], [], anchorBlockHeader, this.contractStore, this.noteStore, this.keyStore, this.addressStore, this.stateMachine.node, this.stateMachine.anchorBlockStore, this.recipientTaggingStore, this.senderAddressBookStore, this.capsuleStore, this.privateEventStore, this.jobId);
443
- const acirExecutionResult = await new WASMSimulator().executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback()).catch((err)=>{
620
+ const simulator = new WASMSimulator();
621
+ const utilityExecutor = async (syncCall, execScopes)=>{
622
+ await this.executeUtilityCall(syncCall, {
623
+ scopes: execScopes,
624
+ jobId,
625
+ authorizedUtilityCallTargets
626
+ });
627
+ };
628
+ const oracle = new UtilityExecutionOracle({
629
+ callContext: CallContext.from({
630
+ msgSender: from,
631
+ contractAddress: call.to,
632
+ functionSelector: call.selector,
633
+ isStaticCall: true
634
+ }),
635
+ authWitnesses: [],
636
+ capsules: [],
637
+ anchorBlockHeader,
638
+ anchoredContractData,
639
+ noteStore: this.noteStore,
640
+ keyStore: this.keyStore,
641
+ addressStore: this.addressStore,
642
+ aztecNode: this.stateMachine.node,
643
+ recipientTaggingStore: this.recipientTaggingStore,
644
+ taggingSecretSourcesStore: this.taggingSecretSourcesStore,
645
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
646
+ factService: new FactService(this.factStore, scopes),
647
+ privateEventStore: this.privateEventStore,
648
+ txResolver: this.stateMachine.txResolver,
649
+ contractSyncService: this.stateMachine.contractSyncService,
650
+ l2TipsStore: this.stateMachine.l2TipsProvider,
651
+ jobId,
652
+ scopes,
653
+ simulator,
654
+ utilityExecutor,
655
+ hooks: composeHooks({
656
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets)
657
+ }),
658
+ // Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
659
+ transientArrayService: new TransientArrayService()
660
+ });
661
+ const acirExecutionResult = await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle)).catch((err)=>{
444
662
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
445
663
  throw new ExecutionError(err.message, {
446
664
  contractAddress: call.to,
@@ -449,21 +667,30 @@ export class TXEOracleTopLevelContext {
449
667
  cause: err
450
668
  });
451
669
  });
452
- this.logger.verbose(`Utility simulation for ${call.to}.${call.selector} completed`);
670
+ this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
453
671
  return witnessMapToFields(acirExecutionResult.returnWitness);
454
672
  } catch (err) {
455
- throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility simulation'));
673
+ throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
456
674
  }
457
675
  }
458
676
  close() {
459
677
  this.logger.debug('Exiting Top Level Context');
460
678
  return [
461
679
  this.nextBlockTimestamp,
462
- this.authwits
680
+ this.authwits,
681
+ this.taggingSecretStrategies
463
682
  ];
464
683
  }
465
684
  async getLastBlockNumber() {
466
- const header = await this.stateMachine.node.getBlockHeader('latest');
467
- return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
685
+ const block = await this.stateMachine.node.getBlock('latest');
686
+ return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
687
+ }
688
+ buildAuthorizeUtilityCallHook(callerContext, authorizedTargets) {
689
+ if (authorizedTargets.length === 0) {
690
+ return undefined;
691
+ }
692
+ return (req)=>Promise.resolve({
693
+ authorized: req.callerContext === callerContext && authorizedTargets.some((t)=>t.equals(req.target))
694
+ });
468
695
  }
469
696
  }