@aztec/txe 0.0.1-commit.c7c42ec → 0.0.1-commit.c949de6bc
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.
- package/dest/constants.d.ts +3 -0
- package/dest/constants.d.ts.map +1 -0
- package/dest/constants.js +2 -0
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +82 -50
- package/dest/oracle/interfaces.d.ts +6 -5
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.d.ts +3 -3
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +6 -6
- package/dest/oracle/txe_oracle_top_level_context.d.ts +8 -7
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +123 -38
- package/dest/rpc_translator.d.ts +21 -15
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +92 -55
- package/dest/state_machine/archiver.d.ts +20 -67
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +59 -178
- package/dest/state_machine/dummy_p2p_client.d.ts +20 -15
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +39 -24
- package/dest/state_machine/global_variable_builder.d.ts +2 -2
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +1 -1
- package/dest/state_machine/index.d.ts +5 -5
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +35 -12
- package/dest/state_machine/mock_epoch_cache.d.ts +9 -6
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +14 -7
- package/dest/state_machine/synchronizer.d.ts +3 -3
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/txe_session.d.ts +12 -7
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +122 -28
- package/dest/util/encoding.d.ts +17 -17
- package/dest/util/txe_public_contract_data_source.d.ts +2 -3
- package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
- package/dest/util/txe_public_contract_data_source.js +5 -22
- package/dest/utils/block_creation.d.ts +4 -4
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +18 -5
- package/dest/utils/tx_effect_creation.d.ts +2 -3
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +3 -6
- package/package.json +16 -16
- package/src/constants.ts +3 -0
- package/src/index.ts +83 -49
- package/src/oracle/interfaces.ts +8 -3
- package/src/oracle/txe_oracle_public_context.ts +6 -8
- package/src/oracle/txe_oracle_top_level_context.ts +163 -79
- package/src/rpc_translator.ts +97 -56
- package/src/state_machine/archiver.ts +54 -220
- package/src/state_machine/dummy_p2p_client.ts +55 -32
- package/src/state_machine/global_variable_builder.ts +1 -1
- package/src/state_machine/index.ts +49 -11
- package/src/state_machine/mock_epoch_cache.ts +15 -11
- package/src/state_machine/synchronizer.ts +2 -2
- package/src/txe_session.ts +151 -71
- package/src/util/txe_public_contract_data_source.ts +10 -36
- package/src/utils/block_creation.ts +19 -16
- package/src/utils/tx_effect_creation.ts +3 -11
- package/dest/util/txe_contract_store.d.ts +0 -12
- package/dest/util/txe_contract_store.d.ts.map +0 -1
- package/dest/util/txe_contract_store.js +0 -22
- package/src/util/txe_contract_store.ts +0 -36
|
@@ -12,9 +12,11 @@ import { Fr } from '@aztec/foundation/curves/bn254';
|
|
|
12
12
|
import { LogLevels, type Logger, applyStringFormatting, createLogger } from '@aztec/foundation/log';
|
|
13
13
|
import { TestDateProvider } from '@aztec/foundation/timer';
|
|
14
14
|
import type { KeyStore } from '@aztec/key-store';
|
|
15
|
+
import type { AccessScopes } from '@aztec/pxe/client/lazy';
|
|
15
16
|
import {
|
|
16
17
|
AddressStore,
|
|
17
18
|
CapsuleStore,
|
|
19
|
+
type ContractStore,
|
|
18
20
|
NoteStore,
|
|
19
21
|
ORACLE_VERSION,
|
|
20
22
|
PrivateEventStore,
|
|
@@ -49,7 +51,7 @@ import {
|
|
|
49
51
|
PublicContractsDB,
|
|
50
52
|
PublicProcessor,
|
|
51
53
|
} from '@aztec/simulator/server';
|
|
52
|
-
import { type ContractArtifact, EventSelector, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
54
|
+
import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
53
55
|
import { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
54
56
|
import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
55
57
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
@@ -80,10 +82,9 @@ import {
|
|
|
80
82
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
81
83
|
import { ForkCheckpoint } from '@aztec/world-state';
|
|
82
84
|
|
|
85
|
+
import { DEFAULT_ADDRESS } from '../constants.js';
|
|
83
86
|
import type { TXEStateMachine } from '../state_machine/index.js';
|
|
84
|
-
import { DEFAULT_ADDRESS } from '../txe_session.js';
|
|
85
87
|
import type { TXEAccountStore } from '../util/txe_account_store.js';
|
|
86
|
-
import type { TXEContractStore } from '../util/txe_contract_store.js';
|
|
87
88
|
import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
|
|
88
89
|
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
89
90
|
import type { ITxeExecutionOracle } from './interfaces.js';
|
|
@@ -96,7 +97,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
96
97
|
|
|
97
98
|
constructor(
|
|
98
99
|
private stateMachine: TXEStateMachine,
|
|
99
|
-
private contractStore:
|
|
100
|
+
private contractStore: ContractStore,
|
|
100
101
|
private noteStore: NoteStore,
|
|
101
102
|
private keyStore: KeyStore,
|
|
102
103
|
private addressStore: AddressStore,
|
|
@@ -130,13 +131,14 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
130
131
|
}
|
|
131
132
|
|
|
132
133
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
133
|
-
|
|
134
|
+
utilityLog(level: number, message: string, fields: Fr[]): Promise<void> {
|
|
134
135
|
if (!LogLevels[level]) {
|
|
135
|
-
throw new Error(`Invalid
|
|
136
|
+
throw new Error(`Invalid log level: ${level}`);
|
|
136
137
|
}
|
|
137
138
|
const levelName = LogLevels[level];
|
|
138
139
|
|
|
139
140
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
|
|
141
|
+
return Promise.resolve();
|
|
140
142
|
}
|
|
141
143
|
|
|
142
144
|
txeGetDefaultAddress(): AztecAddress {
|
|
@@ -156,7 +158,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
156
158
|
}
|
|
157
159
|
|
|
158
160
|
async txeGetLastTxEffects() {
|
|
159
|
-
const
|
|
161
|
+
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
162
|
+
const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
|
|
160
163
|
|
|
161
164
|
if (block!.body.txEffects.length != 1) {
|
|
162
165
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
@@ -168,6 +171,25 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
168
171
|
return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
|
|
169
172
|
}
|
|
170
173
|
|
|
174
|
+
async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
|
|
175
|
+
if (contractAddress.equals(DEFAULT_ADDRESS)) {
|
|
176
|
+
this.logger.debug(`Skipping sync in txeGetPrivateEvents because the events correspond to the default address.`);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
181
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
182
|
+
contractAddress,
|
|
183
|
+
null,
|
|
184
|
+
async (call, execScopes) => {
|
|
185
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
186
|
+
},
|
|
187
|
+
blockHeader,
|
|
188
|
+
jobId,
|
|
189
|
+
[scope],
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
171
193
|
async txeGetPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
|
|
172
194
|
return (
|
|
173
195
|
await this.privateEventStore.getPrivateEvents(selector, {
|
|
@@ -207,7 +229,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
207
229
|
await this.txeAddAccount(artifact, instance, secret);
|
|
208
230
|
} else {
|
|
209
231
|
await this.contractStore.addContractInstance(instance);
|
|
210
|
-
await this.contractStore.addContractArtifact(
|
|
232
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
211
233
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
212
234
|
}
|
|
213
235
|
}
|
|
@@ -217,7 +239,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
217
239
|
|
|
218
240
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
219
241
|
await this.contractStore.addContractInstance(instance);
|
|
220
|
-
await this.contractStore.addContractArtifact(
|
|
242
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
221
243
|
|
|
222
244
|
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
223
245
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
@@ -281,6 +303,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
281
303
|
args: Fr[],
|
|
282
304
|
argsHash: Fr = Fr.zero(),
|
|
283
305
|
isStaticCall: boolean = false,
|
|
306
|
+
jobId: string,
|
|
284
307
|
) {
|
|
285
308
|
this.logger.verbose(
|
|
286
309
|
`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
@@ -294,61 +317,77 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
294
317
|
throw new Error(message);
|
|
295
318
|
}
|
|
296
319
|
|
|
320
|
+
// When `from` is the zero address (e.g. when deploying a new account contract), we return an
|
|
321
|
+
// empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
|
|
322
|
+
const effectiveScopes = from.isZero() ? [] : [from];
|
|
323
|
+
|
|
324
|
+
// Sync notes before executing private function to discover notes from previous transactions
|
|
325
|
+
const utilityExecutor = async (call: FunctionCall, execScopes: AccessScopes) => {
|
|
326
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
330
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
331
|
+
targetContractAddress,
|
|
332
|
+
functionSelector,
|
|
333
|
+
utilityExecutor,
|
|
334
|
+
blockHeader,
|
|
335
|
+
jobId,
|
|
336
|
+
effectiveScopes,
|
|
337
|
+
);
|
|
338
|
+
|
|
297
339
|
const blockNumber = await this.txeGetNextBlockNumber();
|
|
298
340
|
|
|
299
341
|
const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
|
|
300
342
|
|
|
301
343
|
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
302
|
-
|
|
303
344
|
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
304
|
-
|
|
305
345
|
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
306
346
|
|
|
307
347
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
308
348
|
|
|
309
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
310
|
-
|
|
311
349
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
312
350
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
351
|
+
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
352
|
+
// Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
|
|
353
|
+
// marking all side effects as revertible.
|
|
354
|
+
const minRevertibleSideEffectCounter = 1;
|
|
355
|
+
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
313
356
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
314
357
|
|
|
315
358
|
const simulator = new WASMSimulator();
|
|
316
359
|
|
|
317
|
-
const privateExecutionOracle = new PrivateExecutionOracle(
|
|
360
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
318
361
|
argsHash,
|
|
319
362
|
txContext,
|
|
320
363
|
callContext,
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
[],
|
|
327
|
-
HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
364
|
+
anchorBlockHeader: blockHeader,
|
|
365
|
+
utilityExecutor,
|
|
366
|
+
authWitnesses: Array.from(this.authwits.values()),
|
|
367
|
+
capsules: [],
|
|
368
|
+
executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
328
369
|
noteCache,
|
|
329
370
|
taggingIndexCache,
|
|
330
|
-
this.contractStore,
|
|
331
|
-
this.noteStore,
|
|
332
|
-
this.keyStore,
|
|
333
|
-
this.addressStore,
|
|
334
|
-
this.stateMachine.node,
|
|
335
|
-
this.
|
|
336
|
-
this.
|
|
337
|
-
this.
|
|
338
|
-
this.
|
|
339
|
-
this.
|
|
340
|
-
this.
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
*/
|
|
349
|
-
from,
|
|
371
|
+
contractStore: this.contractStore,
|
|
372
|
+
noteStore: this.noteStore,
|
|
373
|
+
keyStore: this.keyStore,
|
|
374
|
+
addressStore: this.addressStore,
|
|
375
|
+
aztecNode: this.stateMachine.node,
|
|
376
|
+
senderTaggingStore: this.senderTaggingStore,
|
|
377
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
378
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
379
|
+
capsuleStore: this.capsuleStore,
|
|
380
|
+
privateEventStore: this.privateEventStore,
|
|
381
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
382
|
+
jobId,
|
|
383
|
+
totalPublicCalldataCount: 0,
|
|
384
|
+
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
385
|
+
scopes: effectiveScopes,
|
|
386
|
+
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
387
|
+
// contract would perform, including setting senderForTags.
|
|
388
|
+
senderForTags: from,
|
|
350
389
|
simulator,
|
|
351
|
-
);
|
|
390
|
+
});
|
|
352
391
|
|
|
353
392
|
// 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.
|
|
354
393
|
let result: PrivateExecutionResult;
|
|
@@ -375,19 +414,22 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
375
414
|
}),
|
|
376
415
|
);
|
|
377
416
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
result = new PrivateExecutionResult(executionResult, Fr.ZERO, publicFunctionsCalldata);
|
|
417
|
+
noteCache.finish();
|
|
418
|
+
const nonceGenerator = noteCache.getNonceGenerator();
|
|
419
|
+
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
382
420
|
} catch (err) {
|
|
383
421
|
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
384
422
|
}
|
|
385
423
|
|
|
386
|
-
// According to the protocol rules,
|
|
387
|
-
//
|
|
388
|
-
//
|
|
389
|
-
const
|
|
390
|
-
|
|
424
|
+
// According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
|
|
425
|
+
// the nonce generator for the note hashes.
|
|
426
|
+
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
427
|
+
const { publicInputs } = await generateSimulatedProvingResult(
|
|
428
|
+
result,
|
|
429
|
+
(addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
|
|
430
|
+
this.stateMachine.node,
|
|
431
|
+
minRevertibleSideEffectCounter,
|
|
432
|
+
);
|
|
391
433
|
|
|
392
434
|
const globals = makeGlobalVariables();
|
|
393
435
|
globals.blockNumber = blockNumber;
|
|
@@ -398,7 +440,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
398
440
|
|
|
399
441
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
400
442
|
|
|
401
|
-
const
|
|
443
|
+
const bindings = this.logger.getBindings();
|
|
444
|
+
const contractsDB = new PublicContractsDB(
|
|
445
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
446
|
+
bindings,
|
|
447
|
+
);
|
|
402
448
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
403
449
|
const config = PublicSimulatorConfig.from({
|
|
404
450
|
skipFeeEnforcement: true,
|
|
@@ -411,8 +457,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
411
457
|
globals,
|
|
412
458
|
guardedMerkleTrees,
|
|
413
459
|
contractsDB,
|
|
414
|
-
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
|
|
460
|
+
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
|
|
415
461
|
new TestDateProvider(),
|
|
462
|
+
undefined,
|
|
463
|
+
createLogger('simulator:public-processor', bindings),
|
|
416
464
|
);
|
|
417
465
|
|
|
418
466
|
const tx = await Tx.create({
|
|
@@ -509,7 +557,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
509
557
|
|
|
510
558
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
511
559
|
|
|
512
|
-
const
|
|
560
|
+
const bindings2 = this.logger.getBindings();
|
|
561
|
+
const contractsDB = new PublicContractsDB(
|
|
562
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
563
|
+
bindings2,
|
|
564
|
+
);
|
|
513
565
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
514
566
|
const config = PublicSimulatorConfig.from({
|
|
515
567
|
skipFeeEnforcement: true,
|
|
@@ -518,8 +570,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
518
570
|
collectStatistics: false,
|
|
519
571
|
collectCallMetadata: true,
|
|
520
572
|
});
|
|
521
|
-
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
|
|
522
|
-
const processor = new PublicProcessor(
|
|
573
|
+
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
|
|
574
|
+
const processor = new PublicProcessor(
|
|
575
|
+
globals,
|
|
576
|
+
guardedMerkleTrees,
|
|
577
|
+
contractsDB,
|
|
578
|
+
simulator,
|
|
579
|
+
new TestDateProvider(),
|
|
580
|
+
undefined,
|
|
581
|
+
createLogger('simulator:public-processor', bindings2),
|
|
582
|
+
);
|
|
523
583
|
|
|
524
584
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
525
585
|
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
@@ -550,7 +610,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
550
610
|
constantData,
|
|
551
611
|
/*gasUsed=*/ new Gas(0, 0),
|
|
552
612
|
/*feePayer=*/ AztecAddress.zero(),
|
|
553
|
-
/*
|
|
613
|
+
/*expirationTimestamp=*/ 0n,
|
|
554
614
|
inputsForPublic,
|
|
555
615
|
undefined,
|
|
556
616
|
);
|
|
@@ -618,22 +678,45 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
618
678
|
return returnValues ?? [];
|
|
619
679
|
}
|
|
620
680
|
|
|
621
|
-
async
|
|
681
|
+
async txeExecuteUtilityFunction(
|
|
622
682
|
targetContractAddress: AztecAddress,
|
|
623
683
|
functionSelector: FunctionSelector,
|
|
624
684
|
args: Fr[],
|
|
685
|
+
jobId: string,
|
|
625
686
|
) {
|
|
626
687
|
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
627
688
|
if (!artifact) {
|
|
628
689
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
629
690
|
}
|
|
630
691
|
|
|
631
|
-
|
|
692
|
+
// Sync notes before executing utility function to discover notes from previous transactions
|
|
693
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
694
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
695
|
+
targetContractAddress,
|
|
696
|
+
functionSelector,
|
|
697
|
+
async (call, execScopes) => {
|
|
698
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
699
|
+
},
|
|
700
|
+
blockHeader,
|
|
701
|
+
jobId,
|
|
702
|
+
'ALL_SCOPES',
|
|
703
|
+
);
|
|
704
|
+
|
|
705
|
+
const call = FunctionCall.from({
|
|
632
706
|
name: artifact.name,
|
|
633
|
-
selector: functionSelector,
|
|
634
707
|
to: targetContractAddress,
|
|
635
|
-
|
|
708
|
+
selector: functionSelector,
|
|
709
|
+
type: FunctionType.UTILITY,
|
|
710
|
+
hideMsgSender: false,
|
|
711
|
+
isStatic: false,
|
|
712
|
+
args,
|
|
713
|
+
returnTypes: [],
|
|
714
|
+
});
|
|
636
715
|
|
|
716
|
+
return this.executeUtilityCall(call, 'ALL_SCOPES', jobId);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
private async executeUtilityCall(call: FunctionCall, scopes: AccessScopes, jobId: string): Promise<Fr[]> {
|
|
637
720
|
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
638
721
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
639
722
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
@@ -646,24 +729,25 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
646
729
|
|
|
647
730
|
try {
|
|
648
731
|
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
649
|
-
const oracle = new UtilityExecutionOracle(
|
|
650
|
-
call.to,
|
|
651
|
-
[],
|
|
652
|
-
[],
|
|
732
|
+
const oracle = new UtilityExecutionOracle({
|
|
733
|
+
contractAddress: call.to,
|
|
734
|
+
authWitnesses: [],
|
|
735
|
+
capsules: [],
|
|
653
736
|
anchorBlockHeader,
|
|
654
|
-
this.contractStore,
|
|
655
|
-
this.noteStore,
|
|
656
|
-
this.keyStore,
|
|
657
|
-
this.addressStore,
|
|
658
|
-
this.stateMachine.node,
|
|
659
|
-
this.
|
|
660
|
-
this.
|
|
661
|
-
this.
|
|
662
|
-
this.
|
|
663
|
-
|
|
664
|
-
|
|
737
|
+
contractStore: this.contractStore,
|
|
738
|
+
noteStore: this.noteStore,
|
|
739
|
+
keyStore: this.keyStore,
|
|
740
|
+
addressStore: this.addressStore,
|
|
741
|
+
aztecNode: this.stateMachine.node,
|
|
742
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
743
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
744
|
+
capsuleStore: this.capsuleStore,
|
|
745
|
+
privateEventStore: this.privateEventStore,
|
|
746
|
+
jobId,
|
|
747
|
+
scopes,
|
|
748
|
+
});
|
|
665
749
|
const acirExecutionResult = await new WASMSimulator()
|
|
666
|
-
.executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
750
|
+
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
667
751
|
.catch((err: Error) => {
|
|
668
752
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
669
753
|
throw new ExecutionError(
|
|
@@ -677,10 +761,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
677
761
|
);
|
|
678
762
|
});
|
|
679
763
|
|
|
680
|
-
this.logger.verbose(`Utility
|
|
764
|
+
this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
|
|
681
765
|
return witnessMapToFields(acirExecutionResult.returnWitness);
|
|
682
766
|
} catch (err) {
|
|
683
|
-
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility
|
|
767
|
+
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
|
|
684
768
|
}
|
|
685
769
|
}
|
|
686
770
|
|