@aztec/txe 0.0.1-commit.03f7ef2 → 0.0.1-commit.04d373f

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 (141) hide show
  1. package/dest/ContractClassRegistry-KKNT527R.js +3 -0
  2. package/dest/ContractClassRegistry-KKNT527R.js.map +7 -0
  3. package/dest/ContractInstanceRegistry-GSKBNL3Q.js +3 -0
  4. package/dest/ContractInstanceRegistry-GSKBNL3Q.js.map +7 -0
  5. package/dest/FeeJuice-GUJ5O6GB.js +3 -0
  6. package/dest/FeeJuice-GUJ5O6GB.js.map +7 -0
  7. package/dest/MultiCallEntrypoint-ZQPCKVKL.js +3 -0
  8. package/dest/MultiCallEntrypoint-ZQPCKVKL.js.map +7 -0
  9. package/dest/SchnorrAccount-QIXE5DXA.js +3 -0
  10. package/dest/SchnorrAccount-QIXE5DXA.js.map +7 -0
  11. package/dest/bin/check_txe_oracle_version.d.ts +2 -0
  12. package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
  13. package/dest/bin/check_txe_oracle_version.js +32 -0
  14. package/dest/bin/index.js +3 -30
  15. package/dest/bin/index.js.map +7 -0
  16. package/dest/chunk-BJVAAXNA.js +3 -0
  17. package/dest/chunk-BJVAAXNA.js.map +7 -0
  18. package/dest/chunk-DF6RMOC6.js +304 -0
  19. package/dest/chunk-DF6RMOC6.js.map +7 -0
  20. package/dest/chunk-PPJTNNUG.js +265 -0
  21. package/dest/chunk-PPJTNNUG.js.map +7 -0
  22. package/dest/constants.d.ts +5 -0
  23. package/dest/constants.d.ts.map +1 -0
  24. package/dest/constants.js +7 -0
  25. package/dest/dispatcher_pool.d.ts +67 -0
  26. package/dest/dispatcher_pool.d.ts.map +1 -0
  27. package/dest/dispatcher_pool.js +284 -0
  28. package/dest/index.d.ts +188 -7
  29. package/dest/index.d.ts.map +1 -1
  30. package/dest/index.js +148 -75
  31. package/dest/metafile.json +38147 -0
  32. package/dest/msgpackr_fr_extension.d.ts +2 -0
  33. package/dest/msgpackr_fr_extension.d.ts.map +1 -0
  34. package/dest/msgpackr_fr_extension.js +21 -0
  35. package/dest/oracle/interfaces.d.ts +40 -28
  36. package/dest/oracle/interfaces.d.ts.map +1 -1
  37. package/dest/oracle/txe_oracle_public_context.d.ts +18 -13
  38. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  39. package/dest/oracle/txe_oracle_public_context.js +31 -16
  40. package/dest/oracle/txe_oracle_top_level_context.d.ts +49 -31
  41. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  42. package/dest/oracle/txe_oracle_top_level_context.js +265 -119
  43. package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
  44. package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
  45. package/dest/oracle/txe_private_execution_oracle.js +15 -0
  46. package/dest/rpc_server.d.ts +14 -0
  47. package/dest/rpc_server.d.ts.map +1 -0
  48. package/dest/rpc_server.js +78 -0
  49. package/dest/rpc_translator.d.ts +144 -82
  50. package/dest/rpc_translator.d.ts.map +1 -1
  51. package/dest/rpc_translator.js +599 -238
  52. package/dest/server.bundle.js +3 -0
  53. package/dest/server.bundle.js.map +7 -0
  54. package/dest/state_machine/archiver.d.ts +20 -67
  55. package/dest/state_machine/archiver.d.ts.map +1 -1
  56. package/dest/state_machine/archiver.js +65 -182
  57. package/dest/state_machine/dummy_p2p_client.d.ts +28 -17
  58. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  59. package/dest/state_machine/dummy_p2p_client.js +51 -24
  60. package/dest/state_machine/global_variable_builder.d.ts +9 -4
  61. package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
  62. package/dest/state_machine/global_variable_builder.js +10 -4
  63. package/dest/state_machine/index.d.ts +11 -7
  64. package/dest/state_machine/index.d.ts.map +1 -1
  65. package/dest/state_machine/index.js +57 -16
  66. package/dest/state_machine/mock_epoch_cache.d.ts +26 -8
  67. package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
  68. package/dest/state_machine/mock_epoch_cache.js +49 -9
  69. package/dest/state_machine/synchronizer.d.ts +6 -6
  70. package/dest/state_machine/synchronizer.d.ts.map +1 -1
  71. package/dest/state_machine/synchronizer.js +4 -4
  72. package/dest/txe_oracle_version.d.ts +17 -0
  73. package/dest/txe_oracle_version.d.ts.map +1 -0
  74. package/dest/txe_oracle_version.js +14 -0
  75. package/dest/txe_session.d.ts +83 -19
  76. package/dest/txe_session.d.ts.map +1 -1
  77. package/dest/txe_session.js +291 -66
  78. package/dest/utils/block_creation.d.ts +4 -4
  79. package/dest/utils/block_creation.d.ts.map +1 -1
  80. package/dest/utils/block_creation.js +18 -5
  81. package/dest/utils/encoding.d.ts +191 -0
  82. package/dest/utils/encoding.d.ts.map +1 -0
  83. package/dest/{util → utils}/encoding.js +7 -2
  84. package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
  85. package/dest/utils/expected_failure_error.d.ts.map +1 -0
  86. package/dest/utils/tx_effect_creation.d.ts +2 -3
  87. package/dest/utils/tx_effect_creation.d.ts.map +1 -1
  88. package/dest/utils/tx_effect_creation.js +3 -6
  89. package/dest/utils/txe_account_store.d.ts +10 -0
  90. package/dest/utils/txe_account_store.d.ts.map +1 -0
  91. package/dest/{util/txe_account_data_provider.js → utils/txe_account_store.js} +1 -1
  92. package/dest/utils/txe_public_contract_data_source.d.ts +20 -0
  93. package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
  94. package/dest/utils/txe_public_contract_data_source.js +48 -0
  95. package/dest/worker.bundle.js +3 -0
  96. package/dest/worker.bundle.js.map +7 -0
  97. package/dest/worker.d.ts +2 -0
  98. package/dest/worker.d.ts.map +1 -0
  99. package/dest/worker.js +92 -0
  100. package/package.json +38 -22
  101. package/src/bin/check_txe_oracle_version.ts +37 -0
  102. package/src/bin/index.ts +11 -2
  103. package/src/constants.ts +9 -0
  104. package/src/dispatcher_pool.ts +316 -0
  105. package/src/index.ts +166 -80
  106. package/src/msgpackr_fr_extension.ts +23 -0
  107. package/src/oracle/interfaces.ts +48 -34
  108. package/src/oracle/txe_oracle_public_context.ts +46 -18
  109. package/src/oracle/txe_oracle_top_level_context.ts +322 -169
  110. package/src/oracle/txe_private_execution_oracle.ts +30 -0
  111. package/src/rpc_server.ts +87 -0
  112. package/src/rpc_translator.ts +687 -326
  113. package/src/state_machine/archiver.ts +69 -220
  114. package/src/state_machine/dummy_p2p_client.ts +80 -37
  115. package/src/state_machine/global_variable_builder.ts +19 -4
  116. package/src/state_machine/index.ts +73 -16
  117. package/src/state_machine/mock_epoch_cache.ts +61 -14
  118. package/src/state_machine/synchronizer.ts +6 -6
  119. package/src/txe_oracle_version.ts +17 -0
  120. package/src/txe_session.ts +439 -132
  121. package/src/utils/block_creation.ts +19 -16
  122. package/src/{util → utils}/encoding.ts +8 -2
  123. package/src/utils/tx_effect_creation.ts +3 -11
  124. package/src/{util/txe_account_data_provider.ts → utils/txe_account_store.ts} +1 -1
  125. package/src/utils/txe_public_contract_data_source.ts +58 -0
  126. package/src/worker.ts +98 -0
  127. package/dest/util/encoding.d.ts +0 -720
  128. package/dest/util/encoding.d.ts.map +0 -1
  129. package/dest/util/expected_failure_error.d.ts.map +0 -1
  130. package/dest/util/txe_account_data_provider.d.ts +0 -10
  131. package/dest/util/txe_account_data_provider.d.ts.map +0 -1
  132. package/dest/util/txe_contract_data_provider.d.ts +0 -12
  133. package/dest/util/txe_contract_data_provider.d.ts.map +0 -1
  134. package/dest/util/txe_contract_data_provider.js +0 -22
  135. package/dest/util/txe_public_contract_data_source.d.ts +0 -21
  136. package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
  137. package/dest/util/txe_public_contract_data_source.js +0 -67
  138. package/src/util/txe_contract_data_provider.ts +0 -36
  139. package/src/util/txe_public_contract_data_source.ts +0 -86
  140. /package/dest/{util → utils}/expected_failure_error.js +0 -0
  141. /package/src/{util → utils}/expected_failure_error.ts +0 -0
@@ -1,40 +1,42 @@
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';
7
+ import { CapsuleService, ORACLE_VERSION_MAJOR, composeHooks, enrichPublicSimulationError } from '@aztec/pxe/server';
8
8
  import { ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache, Oracle, PrivateExecutionOracle, UtilityExecutionOracle, 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
- import { FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
11
+ import { FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
12
12
  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 { hashPublicKey } from '@aztec/stdlib/keys';
19
20
  import { ChonkProof } from '@aztec/stdlib/proofs';
20
21
  import { makeGlobalVariables } from '@aztec/stdlib/testing';
21
22
  import { MerkleTreeId } from '@aztec/stdlib/trees';
22
23
  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 '../txe_session.js';
25
- import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
24
+ import { ForkCheckpoint } from '@aztec/world-state/native';
25
+ import { DEFAULT_ADDRESS } from '../constants.js';
26
26
  import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
27
+ import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
27
28
  export class TXEOracleTopLevelContext {
28
29
  stateMachine;
29
- contractDataProvider;
30
- noteDataProvider;
30
+ contractStore;
31
+ noteStore;
31
32
  keyStore;
32
- addressDataProvider;
33
- accountDataProvider;
34
- senderTaggingDataProvider;
35
- recipientTaggingDataProvider;
36
- capsuleDataProvider;
37
- privateEventDataProvider;
33
+ addressStore;
34
+ accountStore;
35
+ senderTaggingStore;
36
+ recipientTaggingStore;
37
+ senderAddressBookStore;
38
+ capsuleStore;
39
+ privateEventStore;
38
40
  nextBlockTimestamp;
39
41
  version;
40
42
  chainId;
@@ -42,17 +44,18 @@ export class TXEOracleTopLevelContext {
42
44
  isMisc;
43
45
  isTxe;
44
46
  logger;
45
- constructor(stateMachine, contractDataProvider, noteDataProvider, keyStore, addressDataProvider, accountDataProvider, senderTaggingDataProvider, recipientTaggingDataProvider, capsuleDataProvider, privateEventDataProvider, nextBlockTimestamp, version, chainId, authwits){
47
+ constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, senderAddressBookStore, capsuleStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits){
46
48
  this.stateMachine = stateMachine;
47
- this.contractDataProvider = contractDataProvider;
48
- this.noteDataProvider = noteDataProvider;
49
+ this.contractStore = contractStore;
50
+ this.noteStore = noteStore;
49
51
  this.keyStore = keyStore;
50
- this.addressDataProvider = addressDataProvider;
51
- this.accountDataProvider = accountDataProvider;
52
- this.senderTaggingDataProvider = senderTaggingDataProvider;
53
- this.recipientTaggingDataProvider = recipientTaggingDataProvider;
54
- this.capsuleDataProvider = capsuleDataProvider;
55
- this.privateEventDataProvider = privateEventDataProvider;
52
+ this.addressStore = addressStore;
53
+ this.accountStore = accountStore;
54
+ this.senderTaggingStore = senderTaggingStore;
55
+ this.recipientTaggingStore = recipientTaggingStore;
56
+ this.senderAddressBookStore = senderAddressBookStore;
57
+ this.capsuleStore = capsuleStore;
58
+ this.privateEventStore = privateEventStore;
56
59
  this.nextBlockTimestamp = nextBlockTimestamp;
57
60
  this.version = version;
58
61
  this.chainId = chainId;
@@ -62,53 +65,84 @@ export class TXEOracleTopLevelContext {
62
65
  this.logger = createLogger('txe:top_level_context');
63
66
  this.logger.debug('Entering Top Level Context');
64
67
  }
65
- utilityAssertCompatibleOracleVersion(version) {
66
- if (version !== ORACLE_VERSION) {
67
- throw new Error(`Incompatible oracle version. TXE is using version '${ORACLE_VERSION}', but got a request for '${version}'.`);
68
+ contractOracleVersion;
69
+ assertCompatibleOracleVersion(major, minor) {
70
+ if (major !== ORACLE_VERSION_MAJOR) {
71
+ 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.';
72
+ throw new Error(`Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`);
68
73
  }
74
+ this.contractOracleVersion = {
75
+ major,
76
+ minor
77
+ };
78
+ }
79
+ // Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
80
+ nonOracleFunctionGetContractOracleVersion() {
81
+ return this.contractOracleVersion;
69
82
  }
70
83
  // This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
71
84
  // setup.
72
- utilityGetRandomField() {
85
+ getRandomField() {
73
86
  return Fr.random();
74
87
  }
75
88
  // We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
76
- utilityDebugLog(level, message, fields) {
89
+ log(level, message, fields) {
77
90
  if (!LogLevels[level]) {
78
- throw new Error(`Invalid debug log level: ${level}`);
91
+ throw new Error(`Invalid log level: ${level}`);
79
92
  }
80
93
  const levelName = LogLevels[level];
81
94
  this.logger[levelName](`${applyStringFormatting(message, fields)}`, {
82
95
  module: `${this.logger.module}:debug_log`
83
96
  });
97
+ return Promise.resolve();
84
98
  }
85
- txeGetDefaultAddress() {
99
+ getDefaultAddress() {
86
100
  return DEFAULT_ADDRESS;
87
101
  }
88
- async txeGetNextBlockNumber() {
102
+ async getNextBlockNumber() {
89
103
  return BlockNumber(await this.getLastBlockNumber() + 1);
90
104
  }
91
- txeGetNextBlockTimestamp() {
105
+ getNextBlockTimestamp() {
92
106
  return Promise.resolve(this.nextBlockTimestamp);
93
107
  }
94
- async txeGetLastBlockTimestamp() {
95
- return (await this.stateMachine.node.getBlockHeader('latest')).globalVariables.timestamp;
108
+ async getLastBlockTimestamp() {
109
+ return (await this.stateMachine.node.getBlockData('latest')).header.globalVariables.timestamp;
96
110
  }
97
- async txeGetLastTxEffects() {
98
- const block = await this.stateMachine.archiver.getL2Block('latest');
111
+ async getLastTxEffects() {
112
+ const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
113
+ const block = await this.stateMachine.archiver.getBlock({
114
+ number: latestBlockNumber
115
+ });
99
116
  if (block.body.txEffects.length != 1) {
100
117
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
101
118
  throw new Error(`Expected a single transaction in the last block, found ${block.body.txEffects.length}`);
102
119
  }
103
120
  const txEffects = block.body.txEffects[0];
121
+ const privateLogs = txEffects.privateLogs;
122
+ if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
123
+ throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
124
+ }
104
125
  return {
105
126
  txHash: txEffects.txHash,
106
127
  noteHashes: txEffects.noteHashes,
107
- nullifiers: txEffects.nullifiers
128
+ nullifiers: txEffects.nullifiers,
129
+ privateLogs
108
130
  };
109
131
  }
110
- async txeGetPrivateEvents(selector, contractAddress, scope) {
111
- return (await this.privateEventDataProvider.getPrivateEvents(selector, {
132
+ async syncContractNonOracleMethod(contractAddress, scope, jobId) {
133
+ if (contractAddress.equals(DEFAULT_ADDRESS)) {
134
+ this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
135
+ return;
136
+ }
137
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
138
+ await this.stateMachine.contractSyncService.ensureContractSynced(contractAddress, null, async (call, execScopes)=>{
139
+ await this.executeUtilityCall(call, execScopes, jobId);
140
+ }, blockHeader, jobId, [
141
+ scope
142
+ ]);
143
+ }
144
+ async getPrivateEvents(selector, contractAddress, scope) {
145
+ return (await this.privateEventStore.getPrivateEvents(selector, {
112
146
  contractAddress,
113
147
  scopes: [
114
148
  scope
@@ -117,62 +151,71 @@ export class TXEOracleTopLevelContext {
117
151
  toBlock: await this.getLastBlockNumber() + 1
118
152
  })).map((e)=>e.packedEvent);
119
153
  }
120
- async txeAdvanceBlocksBy(blocks) {
154
+ async advanceBlocksBy(blocks) {
121
155
  this.logger.debug(`time traveling ${blocks} blocks`);
122
156
  for(let i = 0; i < blocks; i++){
123
157
  await this.mineBlock();
124
158
  }
125
159
  }
126
- txeAdvanceTimestampBy(duration) {
160
+ advanceTimestampBy(duration) {
127
161
  this.logger.debug(`time traveling ${duration} seconds`);
128
162
  this.nextBlockTimestamp += duration;
129
163
  }
130
- async txeDeploy(artifact, instance, secret) {
164
+ deploymentNullifier(address) {
165
+ return siloNullifier(AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
166
+ }
167
+ async deploy(artifact, instance, secret) {
131
168
  // Emit deployment nullifier
132
169
  await this.mineBlock({
133
170
  nullifiers: [
134
- await siloNullifier(AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), instance.address.toField())
171
+ await this.deploymentNullifier(instance.address)
135
172
  ]
136
173
  });
137
174
  if (!secret.equals(Fr.ZERO)) {
138
- await this.txeAddAccount(artifact, instance, secret);
175
+ await this.addAccount(artifact, instance, secret);
139
176
  } else {
140
- await this.contractDataProvider.addContractInstance(instance);
141
- await this.contractDataProvider.addContractArtifact(instance.currentContractClassId, artifact);
177
+ await this.contractStore.addContractInstance(instance);
178
+ await this.contractStore.addContractArtifact(artifact);
142
179
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
143
180
  }
144
181
  }
145
- async txeAddAccount(artifact, instance, secret) {
182
+ /**
183
+ * Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
184
+ */ async mineDeploymentNullifiers(addresses) {
185
+ await this.mineBlock({
186
+ nullifiers: await Promise.all(addresses.map((address)=>this.deploymentNullifier(address)))
187
+ });
188
+ }
189
+ async addAccount(artifact, instance, secret) {
146
190
  const partialAddress = await computePartialAddress(instance);
147
191
  this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
148
- await this.contractDataProvider.addContractInstance(instance);
149
- await this.contractDataProvider.addContractArtifact(instance.currentContractClassId, artifact);
192
+ await this.contractStore.addContractInstance(instance);
193
+ await this.contractStore.addContractArtifact(artifact);
150
194
  const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
151
- await this.accountDataProvider.setAccount(completeAddress.address, completeAddress);
152
- await this.addressDataProvider.addCompleteAddress(completeAddress);
195
+ await this.accountStore.setAccount(completeAddress.address, completeAddress);
196
+ await this.addressStore.addCompleteAddress(completeAddress);
153
197
  this.logger.debug(`Created account ${completeAddress.address}`);
154
198
  return completeAddress;
155
199
  }
156
- async txeCreateAccount(secret) {
200
+ async createAccount(secret) {
157
201
  // This is a foot gun !
158
202
  const completeAddress = await this.keyStore.addAccount(secret, secret);
159
- await this.accountDataProvider.setAccount(completeAddress.address, completeAddress);
160
- await this.addressDataProvider.addCompleteAddress(completeAddress);
203
+ await this.accountStore.setAccount(completeAddress.address, completeAddress);
204
+ await this.addressStore.addCompleteAddress(completeAddress);
161
205
  this.logger.debug(`Created account ${completeAddress.address}`);
162
206
  return completeAddress;
163
207
  }
164
- async txeAddAuthWitness(address, messageHash) {
165
- const account = await this.accountDataProvider.getAccount(address);
166
- const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
208
+ async addAuthWitness(address, messageHash) {
209
+ const account = await this.accountStore.getAccount(address);
210
+ const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
211
+ const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
167
212
  const schnorr = new Schnorr();
168
- const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
169
- const authWitness = new AuthWitness(messageHash, [
170
- ...signature.toBuffer()
171
- ]);
213
+ const signature = await schnorr.constructSignature(messageHash, privateKey);
214
+ const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
172
215
  this.authwits.set(authWitness.requestHash.toString(), authWitness);
173
216
  }
174
217
  async mineBlock(options = {}) {
175
- const blockNumber = await this.txeGetNextBlockNumber();
218
+ const blockNumber = await this.getNextBlockNumber();
176
219
  const txEffect = TxEffect.empty();
177
220
  txEffect.nullifiers = [
178
221
  getSingleTxBlockRequestHash(blockNumber),
@@ -194,30 +237,74 @@ export class TXEOracleTopLevelContext {
194
237
  this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
195
238
  await this.stateMachine.handleL2Block(block);
196
239
  }
197
- async txePrivateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false) {
198
- this.logger.verbose(`Executing external function ${await this.contractDataProvider.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
199
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
240
+ async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, additionalScopes = [], jobId, authorizedUtilityCallTargets, gasSettings) {
241
+ this.logger.verbose(`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
242
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
200
243
  if (!artifact) {
201
244
  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';
202
245
  throw new Error(message);
203
246
  }
204
- const blockNumber = await this.txeGetNextBlockNumber();
205
- const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
206
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
207
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
208
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
247
+ const scopes = from === undefined ? additionalScopes : [
248
+ from,
249
+ ...additionalScopes
250
+ ];
251
+ // Sync notes before executing private function to discover notes from previous transactions
252
+ const utilityExecutor = async (call, execScopes)=>{
253
+ await this.executeUtilityCall(call, execScopes, jobId);
254
+ };
255
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
256
+ await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, scopes);
257
+ const blockNumber = await this.getNextBlockNumber();
258
+ const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
259
+ const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
209
260
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
210
- const blockHeader = await this.stateMachine.anchorBlockDataProvider.getBlockHeader();
211
261
  const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
212
262
  const noteCache = new ExecutionNoteCache(protocolNullifier);
263
+ // In production, the account contract sets the min revertible counter before calling the app function.
264
+ // Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
265
+ // marking all side effects as revertible.
266
+ const minRevertibleSideEffectCounter = 1;
267
+ await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
213
268
  const taggingIndexCache = new ExecutionTaggingIndexCache();
214
269
  const simulator = new WASMSimulator();
215
- 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, /** 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([
216
- new HashedValues(args, argsHash)
217
- ]), noteCache, taggingIndexCache, this.contractDataProvider, this.noteDataProvider, this.keyStore, this.addressDataProvider, this.stateMachine.node, this.stateMachine.anchorBlockDataProvider, this.senderTaggingDataProvider, this.recipientTaggingDataProvider, this.capsuleDataProvider, this.privateEventDataProvider, 0, 1, undefined, undefined, /**
218
- * In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
219
- * contract would perform, including setting senderForTags.
220
- */ from, simulator);
270
+ const privateExecutionOracle = new PrivateExecutionOracle({
271
+ argsHash,
272
+ txContext,
273
+ callContext,
274
+ anchorBlockHeader: blockHeader,
275
+ utilityExecutor,
276
+ authWitnesses: Array.from(this.authwits.values()),
277
+ capsules: [],
278
+ executionCache: HashedValuesCache.create([
279
+ new HashedValues(args, argsHash)
280
+ ]),
281
+ noteCache,
282
+ taggingIndexCache,
283
+ contractStore: this.contractStore,
284
+ noteStore: this.noteStore,
285
+ keyStore: this.keyStore,
286
+ addressStore: this.addressStore,
287
+ aztecNode: this.stateMachine.node,
288
+ senderTaggingStore: this.senderTaggingStore,
289
+ recipientTaggingStore: this.recipientTaggingStore,
290
+ senderAddressBookStore: this.senderAddressBookStore,
291
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
292
+ privateEventStore: this.privateEventStore,
293
+ contractSyncService: this.stateMachine.contractSyncService,
294
+ jobId,
295
+ totalPublicCalldataCount: 0,
296
+ sideEffectCounter: minRevertibleSideEffectCounter,
297
+ scopes,
298
+ // In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
299
+ // contract would perform, including setting senderForTags.
300
+ senderForTags: from,
301
+ simulator,
302
+ messageContextService: this.stateMachine.messageContextService,
303
+ l2TipsStore: this.stateMachine.l2TipsProvider,
304
+ hooks: composeHooks({
305
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(isStaticCall ? 'private view' : 'private', authorizedUtilityCallTargets)
306
+ })
307
+ });
221
308
  // 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.
222
309
  let result;
223
310
  let executionResult;
@@ -229,21 +316,19 @@ export class TXEOracleTopLevelContext {
229
316
  r.publicInputs.publicTeardownCallRequest
230
317
  ]));
231
318
  const publicFunctionsCalldata = await Promise.all(publicCallRequests.map(async (r)=>{
232
- const calldata = await privateExecutionOracle.privateLoadFromExecutionCache(r.calldataHash);
319
+ const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
233
320
  return new HashedValues(calldata, r.calldataHash);
234
321
  }));
235
- // TXE's top level context does not track side effect counters, and as such, minRevertibleSideEffectCounter is always 0.
236
- // This has the unfortunate consequence of always producing revertible nullifiers, which means we
237
- // must set the firstNullifierHint to Fr.ZERO so the txRequestHash is always used as nonce generator
238
- result = new PrivateExecutionResult(executionResult, Fr.ZERO, publicFunctionsCalldata);
322
+ noteCache.finish();
323
+ const nonceGenerator = noteCache.getNonceGenerator();
324
+ result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
239
325
  } catch (err) {
240
326
  throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
241
327
  }
242
- // According to the protocol rules, the nonce generator for the note hashes
243
- // can either be the first nullifier in the tx or the hash of the initial tx request
244
- // if there are none.
245
- const nonceGenerator = result.firstNullifier.equals(Fr.ZERO) ? protocolNullifier : result.firstNullifier;
246
- const { publicInputs } = await generateSimulatedProvingResult(result, nonceGenerator, this.contractDataProvider);
328
+ // According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
329
+ // the nonce generator for the note hashes.
330
+ // We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
331
+ const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>this.contractStore.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
247
332
  const globals = makeGlobalVariables();
248
333
  globals.blockNumber = blockNumber;
249
334
  globals.timestamp = this.nextBlockTimestamp;
@@ -251,7 +336,8 @@ export class TXEOracleTopLevelContext {
251
336
  globals.version = this.version;
252
337
  globals.gasFees = GasFees.empty();
253
338
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
254
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
339
+ const bindings = this.logger.getBindings();
340
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings);
255
341
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
256
342
  const config = PublicSimulatorConfig.from({
257
343
  skipFeeEnforcement: true,
@@ -260,7 +346,7 @@ export class TXEOracleTopLevelContext {
260
346
  collectStatistics: false,
261
347
  collectCallMetadata: true
262
348
  });
263
- const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config), new TestDateProvider());
349
+ const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings), new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings));
264
350
  const tx = await Tx.create({
265
351
  data: publicInputs,
266
352
  chonkProof: ChonkProof.empty(),
@@ -281,7 +367,7 @@ export class TXEOracleTopLevelContext {
281
367
  } else if (!processedTx.revertCode.isOK()) {
282
368
  if (processedTx.revertReason) {
283
369
  try {
284
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
370
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
285
371
  // eslint-disable-next-line no-empty
286
372
  } catch {}
287
373
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -289,10 +375,20 @@ export class TXEOracleTopLevelContext {
289
375
  throw new Error('Contract execution has reverted');
290
376
  }
291
377
  }
378
+ // Walk the nested private-call tree and collect every offchain effect the transaction emitted.
379
+ // PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
380
+ // `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
381
+ // we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
382
+ const offchainEffects = collectNested([
383
+ executionResult
384
+ ], (r)=>r.offchainEffects.map((e)=>e.data));
292
385
  if (isStaticCall) {
293
386
  await checkpoint.revert();
294
387
  await forkedWorldTrees.close();
295
- return executionResult.returnValues ?? [];
388
+ return {
389
+ returnValues: executionResult.returnValues ?? [],
390
+ offchainEffects
391
+ };
296
392
  }
297
393
  const txEffect = TxEffect.empty();
298
394
  txEffect.noteHashes = processedTx.txEffect.noteHashes;
@@ -308,16 +404,16 @@ export class TXEOracleTopLevelContext {
308
404
  ]);
309
405
  await this.stateMachine.handleL2Block(l2Block);
310
406
  await forkedWorldTrees.close();
311
- return executionResult.returnValues ?? [];
407
+ return {
408
+ returnValues: executionResult.returnValues ?? [],
409
+ offchainEffects
410
+ };
312
411
  }
313
- async txePublicCallNewFlow(from, targetContractAddress, calldata, isStaticCall) {
314
- this.logger.verbose(`Executing public function ${await this.contractDataProvider.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
315
- const blockNumber = await this.txeGetNextBlockNumber();
316
- const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
317
- const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
318
- const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
412
+ async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall, gasSettings) {
413
+ this.logger.verbose(`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
414
+ const blockNumber = await this.getNextBlockNumber();
319
415
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
320
- const anchorBlockHeader = await this.stateMachine.anchorBlockDataProvider.getBlockHeader();
416
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
321
417
  const calldataHash = await computeCalldataHash(calldata);
322
418
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
323
419
  const globals = makeGlobalVariables();
@@ -327,7 +423,8 @@ export class TXEOracleTopLevelContext {
327
423
  globals.version = this.version;
328
424
  globals.gasFees = GasFees.empty();
329
425
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
330
- const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractDataProvider));
426
+ const bindings2 = this.logger.getBindings();
427
+ const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings2);
331
428
  const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
332
429
  const config = PublicSimulatorConfig.from({
333
430
  skipFeeEnforcement: true,
@@ -336,8 +433,8 @@ export class TXEOracleTopLevelContext {
336
433
  collectStatistics: false,
337
434
  collectCallMetadata: true
338
435
  });
339
- const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
340
- const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider());
436
+ const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
437
+ const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings2));
341
438
  // We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
342
439
  // kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
343
440
  // side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
@@ -347,10 +444,10 @@ export class TXEOracleTopLevelContext {
347
444
  // The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
348
445
  // may require producing reverts.
349
446
  const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
350
- revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from, targetContractAddress, isStaticCall, calldataHash);
447
+ revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from ?? AztecAddress.NULL_MSG_SENDER, targetContractAddress, isStaticCall, calldataHash);
351
448
  const inputsForPublic = new PartialPrivateTailPublicInputsForPublic(nonRevertibleAccumulatedData, revertibleAccumulatedData, PublicCallRequest.empty());
352
449
  const constantData = new TxConstantData(anchorBlockHeader, txContext, Fr.zero(), Fr.zero());
353
- const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*includeByTimestamp=*/ 0n, inputsForPublic, undefined);
450
+ const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*expirationTimestamp=*/ 0n, inputsForPublic, undefined);
354
451
  const tx = await Tx.create({
355
452
  data: txData,
356
453
  chonkProof: ChonkProof.empty(),
@@ -373,7 +470,7 @@ export class TXEOracleTopLevelContext {
373
470
  } else if (!processedTx.revertCode.isOK()) {
374
471
  if (processedTx.revertReason) {
375
472
  try {
376
- await enrichPublicSimulationError(processedTx.revertReason, this.contractDataProvider, this.logger);
473
+ await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
377
474
  // eslint-disable-next-line no-empty
378
475
  } catch {}
379
476
  throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
@@ -403,17 +500,30 @@ export class TXEOracleTopLevelContext {
403
500
  await forkedWorldTrees.close();
404
501
  return returnValues ?? [];
405
502
  }
406
- async txeSimulateUtilityFunction(targetContractAddress, functionSelector, args) {
407
- const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
503
+ async executeUtilityFunction(targetContractAddress, functionSelector, args, jobId, authorizedUtilityCallTargets) {
504
+ const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
408
505
  if (!artifact) {
409
506
  throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
410
507
  }
411
- const call = {
508
+ // Sync notes before executing utility function to discover notes from previous transactions
509
+ const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
510
+ await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, async (call, execScopes)=>{
511
+ await this.executeUtilityCall(call, execScopes, jobId);
512
+ }, blockHeader, jobId, await this.keyStore.getAccounts());
513
+ const call = FunctionCall.from({
412
514
  name: artifact.name,
515
+ to: targetContractAddress,
413
516
  selector: functionSelector,
414
- to: targetContractAddress
415
- };
416
- const entryPointArtifact = await this.contractDataProvider.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
517
+ type: FunctionType.UTILITY,
518
+ hideMsgSender: false,
519
+ isStatic: false,
520
+ args,
521
+ returnTypes: []
522
+ });
523
+ return this.executeUtilityCall(call, await this.keyStore.getAccounts(), jobId, authorizedUtilityCallTargets);
524
+ }
525
+ async executeUtilityCall(call, scopes, jobId, authorizedUtilityCallTargets = []) {
526
+ const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
417
527
  if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
418
528
  throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
419
529
  }
@@ -422,9 +532,37 @@ export class TXEOracleTopLevelContext {
422
532
  selector: call.selector
423
533
  });
424
534
  try {
425
- const anchorBlockHeader = await this.stateMachine.anchorBlockDataProvider.getBlockHeader();
426
- const oracle = new UtilityExecutionOracle(call.to, [], [], anchorBlockHeader, this.contractDataProvider, this.noteDataProvider, this.keyStore, this.addressDataProvider, this.stateMachine.node, this.stateMachine.anchorBlockDataProvider, this.senderTaggingDataProvider, this.recipientTaggingDataProvider, this.capsuleDataProvider, this.privateEventDataProvider);
427
- const acirExecutionResult = await new WASMSimulator().executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback()).catch((err)=>{
535
+ const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
536
+ const simulator = new WASMSimulator();
537
+ const utilityExecutor = async (syncCall, execScopes)=>{
538
+ await this.executeUtilityCall(syncCall, execScopes, jobId);
539
+ };
540
+ const oracle = new UtilityExecutionOracle({
541
+ contractAddress: call.to,
542
+ authWitnesses: [],
543
+ capsules: [],
544
+ anchorBlockHeader,
545
+ contractStore: this.contractStore,
546
+ noteStore: this.noteStore,
547
+ keyStore: this.keyStore,
548
+ addressStore: this.addressStore,
549
+ aztecNode: this.stateMachine.node,
550
+ recipientTaggingStore: this.recipientTaggingStore,
551
+ senderAddressBookStore: this.senderAddressBookStore,
552
+ capsuleService: new CapsuleService(this.capsuleStore, scopes),
553
+ privateEventStore: this.privateEventStore,
554
+ messageContextService: this.stateMachine.messageContextService,
555
+ contractSyncService: this.stateMachine.contractSyncService,
556
+ l2TipsStore: this.stateMachine.l2TipsProvider,
557
+ jobId,
558
+ scopes,
559
+ simulator,
560
+ hooks: composeHooks({
561
+ authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets)
562
+ }),
563
+ utilityExecutor
564
+ });
565
+ const acirExecutionResult = await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback()).catch((err)=>{
428
566
  err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
429
567
  throw new ExecutionError(err.message, {
430
568
  contractAddress: call.to,
@@ -433,10 +571,10 @@ export class TXEOracleTopLevelContext {
433
571
  cause: err
434
572
  });
435
573
  });
436
- this.logger.verbose(`Utility simulation for ${call.to}.${call.selector} completed`);
574
+ this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
437
575
  return witnessMapToFields(acirExecutionResult.returnWitness);
438
576
  } catch (err) {
439
- throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility simulation'));
577
+ throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
440
578
  }
441
579
  }
442
580
  close() {
@@ -447,7 +585,15 @@ export class TXEOracleTopLevelContext {
447
585
  ];
448
586
  }
449
587
  async getLastBlockNumber() {
450
- const header = await this.stateMachine.node.getBlockHeader('latest');
451
- return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
588
+ const block = await this.stateMachine.node.getBlock('latest');
589
+ return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
590
+ }
591
+ buildAuthorizeUtilityCallHook(callerContext, authorizedTargets) {
592
+ if (authorizedTargets.length === 0) {
593
+ return undefined;
594
+ }
595
+ return (req)=>Promise.resolve({
596
+ authorized: req.callerContext === callerContext && authorizedTargets.some((t)=>t.equals(req.target))
597
+ });
452
598
  }
453
599
  }