@aztec/txe 0.0.1-commit.9ef841308 → 0.0.1-commit.a4600f49

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