@aztec/txe 0.0.1-commit.3100065 → 0.0.1-commit.330febf
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/AuthRegistry-QVGDDH5X.js +3 -0
- package/dest/AuthRegistry-QVGDDH5X.js.map +7 -0
- package/dest/ContractClassRegistry-PVNCKGG7.js +3 -0
- package/dest/ContractClassRegistry-PVNCKGG7.js.map +7 -0
- package/dest/{ContractInstanceRegistry-NADDSLGL.js → ContractInstanceRegistry-WLOZKTR6.js} +1 -1
- package/dest/{ContractInstanceRegistry-NADDSLGL.js.map → ContractInstanceRegistry-WLOZKTR6.js.map} +2 -2
- package/dest/FeeJuice-MAQJU53K.js +3 -0
- package/dest/FeeJuice-MAQJU53K.js.map +7 -0
- package/dest/HandshakeRegistry-GY5CPEPS.js +3 -0
- package/dest/HandshakeRegistry-GY5CPEPS.js.map +7 -0
- package/dest/MultiCallEntrypoint-QG5H33ZZ.js +3 -0
- package/dest/{MultiCallEntrypoint-TGICA67H.js.map → MultiCallEntrypoint-QG5H33ZZ.js.map} +2 -2
- package/dest/SchnorrAccount-ADD65DYA.js +3 -0
- package/dest/SchnorrAccount-ADD65DYA.js.map +7 -0
- package/dest/SchnorrInitializerlessAccount-TWGKRUSY.js +3 -0
- package/dest/SchnorrInitializerlessAccount-TWGKRUSY.js.map +7 -0
- package/dest/bin/check_txe_oracle_version.js +8 -47
- package/dest/bin/index.js +1 -1
- package/dest/chunk-32UHX7YY.js +3 -0
- package/dest/{chunk-PDOEF22H.js → chunk-RVEPNDEP.js} +2 -2
- package/dest/{chunk-PDOEF22H.js.map → chunk-RVEPNDEP.js.map} +2 -2
- package/dest/chunk-XWIMXLKD.js +258 -0
- package/dest/chunk-XWIMXLKD.js.map +7 -0
- package/dest/constants.js +1 -1
- package/dest/metafile.json +2369 -3419
- package/dest/oracle/interfaces.d.ts +6 -2
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/test-resolver/default_fixtures.d.ts +9 -2
- package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -1
- package/dest/oracle/test-resolver/default_fixtures.js +32 -39
- package/dest/oracle/test-resolver/resolver.d.ts +1 -1
- package/dest/oracle/test-resolver/resolver.d.ts.map +1 -1
- package/dest/oracle/test-resolver/resolver.js +2 -2
- package/dest/oracle/txe_oracle_registry.d.ts +5 -3
- package/dest/oracle/txe_oracle_registry.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_registry.js +45 -27
- package/dest/oracle/txe_oracle_top_level_context.d.ts +18 -5
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +375 -272
- package/dest/oracle/txe_oracle_version.d.ts +5 -5
- package/dest/oracle/txe_oracle_version.js +5 -5
- package/dest/rpc_translator.d.ts +4 -1
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +25 -1
- package/dest/server.bundle.js +1 -1
- package/dest/state_machine/mock_epoch_cache.d.ts +2 -1
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +3 -0
- package/dest/state_machine/synchronizer.d.ts +6 -1
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +12 -3
- package/dest/txe_session.d.ts +6 -3
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +25 -9
- package/dest/utils/encoding.d.ts +5 -3
- package/dest/utils/encoding.d.ts.map +1 -1
- package/dest/worker.bundle.js +1 -1
- package/package.json +17 -17
- package/src/bin/check_txe_oracle_version.ts +10 -49
- package/src/constants.ts +1 -1
- package/src/oracle/interfaces.ts +5 -1
- package/src/oracle/test-resolver/default_fixtures.ts +58 -69
- package/src/oracle/test-resolver/resolver.ts +2 -2
- package/src/oracle/txe_oracle_registry.ts +42 -25
- package/src/oracle/txe_oracle_top_level_context.ts +55 -23
- package/src/oracle/txe_oracle_version.ts +5 -5
- package/src/rpc_translator.ts +29 -1
- package/src/state_machine/mock_epoch_cache.ts +4 -0
- package/src/state_machine/synchronizer.ts +18 -3
- package/src/txe_session.ts +31 -9
- package/dest/AuthRegistry-FSRZIMX6.js +0 -3
- package/dest/AuthRegistry-FSRZIMX6.js.map +0 -7
- package/dest/ContractClassRegistry-N6NA3SFA.js +0 -3
- package/dest/ContractClassRegistry-N6NA3SFA.js.map +0 -7
- package/dest/FeeJuice-QBH5JWJV.js +0 -3
- package/dest/FeeJuice-QBH5JWJV.js.map +0 -7
- package/dest/HandshakeRegistry-KKUEU7XW.js +0 -3
- package/dest/HandshakeRegistry-KKUEU7XW.js.map +0 -7
- package/dest/MultiCallEntrypoint-TGICA67H.js +0 -3
- package/dest/SchnorrAccount-J5T6OKR3.js +0 -3
- package/dest/SchnorrAccount-J5T6OKR3.js.map +0 -7
- package/dest/SchnorrInitializerlessAccount-OOES6Q4F.js +0 -3
- package/dest/SchnorrInitializerlessAccount-OOES6Q4F.js.map +0 -7
- package/dest/chunk-BJVAAXNA.js +0 -3
- package/dest/chunk-YP4ODNMQ.js +0 -268
- package/dest/chunk-YP4ODNMQ.js.map +0 -7
- /package/dest/{chunk-BJVAAXNA.js.map → chunk-32UHX7YY.js.map} +0 -0
|
@@ -1,3 +1,68 @@
|
|
|
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
|
+
}
|
|
1
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';
|
|
@@ -7,7 +72,7 @@ import { TestDateProvider } from '@aztec/foundation/timer';
|
|
|
7
72
|
import { AnchoredContractData, CapsuleService, FactService, ORACLE_VERSION_MAJOR, composeHooks, enrichPublicSimulationError } from '@aztec/pxe/server';
|
|
8
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 {
|
|
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';
|
|
@@ -46,13 +111,14 @@ export class TXEOracleTopLevelContext {
|
|
|
46
111
|
chainId;
|
|
47
112
|
authwits;
|
|
48
113
|
taggingSecretStrategies;
|
|
114
|
+
authorizeAllUtilityCallTargets;
|
|
49
115
|
artifactResolver;
|
|
50
116
|
rootPath;
|
|
51
117
|
packageName;
|
|
52
118
|
isMisc;
|
|
53
119
|
isTxe;
|
|
54
120
|
logger;
|
|
55
|
-
constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, taggingSecretSourcesStore, capsuleStore, factStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits, taggingSecretStrategies, artifactResolver, rootPath, packageName){
|
|
121
|
+
constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, taggingSecretSourcesStore, capsuleStore, factStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits, taggingSecretStrategies, authorizeAllUtilityCallTargets, artifactResolver, rootPath, packageName){
|
|
56
122
|
this.stateMachine = stateMachine;
|
|
57
123
|
this.contractStore = contractStore;
|
|
58
124
|
this.noteStore = noteStore;
|
|
@@ -70,6 +136,7 @@ export class TXEOracleTopLevelContext {
|
|
|
70
136
|
this.chainId = chainId;
|
|
71
137
|
this.authwits = authwits;
|
|
72
138
|
this.taggingSecretStrategies = taggingSecretStrategies;
|
|
139
|
+
this.authorizeAllUtilityCallTargets = authorizeAllUtilityCallTargets;
|
|
73
140
|
this.artifactResolver = artifactResolver;
|
|
74
141
|
this.rootPath = rootPath;
|
|
75
142
|
this.packageName = packageName;
|
|
@@ -235,9 +302,8 @@ export class TXEOracleTopLevelContext {
|
|
|
235
302
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
236
303
|
return completeAddress;
|
|
237
304
|
}
|
|
238
|
-
async createAccount(secret) {
|
|
239
|
-
|
|
240
|
-
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), secret);
|
|
305
|
+
async createAccount(secret, partialAddress) {
|
|
306
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
241
307
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
242
308
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
243
309
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -263,6 +329,9 @@ export class TXEOracleTopLevelContext {
|
|
|
263
329
|
apply(AppTaggingSecretKind.UNCONSTRAINED, unconstrainedStrategy);
|
|
264
330
|
apply(AppTaggingSecretKind.CONSTRAINED, constrainedStrategy);
|
|
265
331
|
}
|
|
332
|
+
setAuthorizeAllUtilityCallTargets(authorizeAll) {
|
|
333
|
+
this.authorizeAllUtilityCallTargets = authorizeAll;
|
|
334
|
+
}
|
|
266
335
|
async sendL1ToL2Message(content, secretHash, sender, recipient) {
|
|
267
336
|
// Messages are appended to the tree, so the next free slot is simply the current tree size.
|
|
268
337
|
const { size } = await this.stateMachine.synchronizer.getCommitted().getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
|
|
@@ -299,277 +368,302 @@ export class TXEOracleTopLevelContext {
|
|
|
299
368
|
await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
|
|
300
369
|
}
|
|
301
370
|
async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, additionalScopes = [], jobId, authorizedUtilityCallTargets, gasSettings) {
|
|
302
|
-
const
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
if (!artifact) {
|
|
307
|
-
const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)')) ? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.' : 'Function Artifact does not exist';
|
|
308
|
-
throw new Error(message);
|
|
309
|
-
}
|
|
310
|
-
const scopes = from === undefined ? additionalScopes : [
|
|
311
|
-
from,
|
|
312
|
-
...additionalScopes
|
|
313
|
-
];
|
|
314
|
-
// Sync notes before executing private function to discover notes from previous transactions
|
|
315
|
-
const utilityExecutor = async (call, execScopes)=>{
|
|
316
|
-
await this.executeUtilityCall(call, {
|
|
317
|
-
scopes: execScopes,
|
|
318
|
-
jobId
|
|
319
|
-
});
|
|
371
|
+
const env = {
|
|
372
|
+
stack: [],
|
|
373
|
+
error: void 0,
|
|
374
|
+
hasError: false
|
|
320
375
|
};
|
|
321
|
-
await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, scopes);
|
|
322
|
-
const blockNumber = await this.getNextBlockNumber();
|
|
323
|
-
const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
|
|
324
|
-
const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
|
|
325
|
-
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
326
|
-
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
327
|
-
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
328
|
-
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
329
|
-
// Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
|
|
330
|
-
// marking all side effects as revertible.
|
|
331
|
-
const minRevertibleSideEffectCounter = 1;
|
|
332
|
-
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
333
|
-
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
334
|
-
const simulator = new WASMSimulator();
|
|
335
|
-
const transientArrayService = new TransientArrayService();
|
|
336
|
-
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
337
|
-
argsHash,
|
|
338
|
-
txContext,
|
|
339
|
-
// The TXE does not run the init kernel's salt binding, so no tx-request salt is in scope.
|
|
340
|
-
txRequestSalt: Fr.ZERO,
|
|
341
|
-
callContext,
|
|
342
|
-
anchorBlockHeader: blockHeader,
|
|
343
|
-
utilityExecutor,
|
|
344
|
-
authWitnesses: Array.from(this.authwits.values()),
|
|
345
|
-
capsules: [],
|
|
346
|
-
executionCache: HashedValuesCache.create([
|
|
347
|
-
new HashedValues(args, argsHash)
|
|
348
|
-
]),
|
|
349
|
-
noteCache,
|
|
350
|
-
taggingIndexCache,
|
|
351
|
-
anchoredContractData,
|
|
352
|
-
noteStore: this.noteStore,
|
|
353
|
-
keyStore: this.keyStore,
|
|
354
|
-
addressStore: this.addressStore,
|
|
355
|
-
aztecNode: this.stateMachine.node,
|
|
356
|
-
senderTaggingStore: this.senderTaggingStore,
|
|
357
|
-
recipientTaggingStore: this.recipientTaggingStore,
|
|
358
|
-
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
359
|
-
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
360
|
-
factService: new FactService(this.factStore, scopes),
|
|
361
|
-
privateEventStore: this.privateEventStore,
|
|
362
|
-
contractSyncService: this.stateMachine.contractSyncService,
|
|
363
|
-
jobId,
|
|
364
|
-
totalPublicCalldataCount: 0,
|
|
365
|
-
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
366
|
-
scopes,
|
|
367
|
-
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
368
|
-
// contract would perform, including setting senderForTags.
|
|
369
|
-
senderForTags: from,
|
|
370
|
-
simulator,
|
|
371
|
-
txResolver: this.stateMachine.txResolver,
|
|
372
|
-
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
373
|
-
hooks: composeHooks({
|
|
374
|
-
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(isStaticCall ? 'private view' : 'private', authorizedUtilityCallTargets),
|
|
375
|
-
resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies)
|
|
376
|
-
}),
|
|
377
|
-
transientArrayService
|
|
378
|
-
});
|
|
379
|
-
// Note: This is a slight modification of simulator.run without any of the checks. Maybe we should modify simulator.run with a boolean value to skip checks.
|
|
380
|
-
let result;
|
|
381
|
-
let executionResult;
|
|
382
376
|
try {
|
|
383
|
-
|
|
384
|
-
const
|
|
377
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
378
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
|
|
379
|
+
this.logger.verbose(`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
|
|
380
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
381
|
+
if (!artifact) {
|
|
382
|
+
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';
|
|
383
|
+
throw new Error(message);
|
|
384
|
+
}
|
|
385
|
+
const scopes = from === undefined ? additionalScopes : [
|
|
386
|
+
from,
|
|
387
|
+
...additionalScopes
|
|
388
|
+
];
|
|
389
|
+
// Sync notes before executing private function to discover notes from previous transactions
|
|
390
|
+
const utilityExecutor = async (call, execScopes)=>{
|
|
391
|
+
await this.executeUtilityCall(call, {
|
|
392
|
+
scopes: execScopes,
|
|
393
|
+
jobId
|
|
394
|
+
});
|
|
395
|
+
};
|
|
396
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, scopes);
|
|
397
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
398
|
+
const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
|
|
399
|
+
const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
|
|
400
|
+
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
401
|
+
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
402
|
+
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
403
|
+
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
404
|
+
// Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
|
|
405
|
+
// marking all side effects as revertible.
|
|
406
|
+
const minRevertibleSideEffectCounter = 1;
|
|
407
|
+
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
408
|
+
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
409
|
+
const simulator = new WASMSimulator();
|
|
410
|
+
const transientArrayService = new TransientArrayService();
|
|
411
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
412
|
+
argsHash,
|
|
413
|
+
txContext,
|
|
414
|
+
txRequestSalt: Fr.ZERO,
|
|
415
|
+
callContext,
|
|
416
|
+
anchorBlockHeader: blockHeader,
|
|
417
|
+
utilityExecutor,
|
|
418
|
+
authWitnesses: Array.from(this.authwits.values()),
|
|
419
|
+
capsules: [],
|
|
420
|
+
executionCache: HashedValuesCache.create([
|
|
421
|
+
new HashedValues(args, argsHash)
|
|
422
|
+
]),
|
|
423
|
+
noteCache,
|
|
424
|
+
taggingIndexCache,
|
|
425
|
+
anchoredContractData,
|
|
426
|
+
noteStore: this.noteStore,
|
|
427
|
+
keyStore: this.keyStore,
|
|
428
|
+
addressStore: this.addressStore,
|
|
429
|
+
aztecNode: this.stateMachine.node,
|
|
430
|
+
senderTaggingStore: this.senderTaggingStore,
|
|
431
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
432
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
433
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
434
|
+
factService: new FactService(this.factStore, scopes),
|
|
435
|
+
privateEventStore: this.privateEventStore,
|
|
436
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
437
|
+
jobId,
|
|
438
|
+
totalPublicCalldataCount: 0,
|
|
439
|
+
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
440
|
+
scopes,
|
|
441
|
+
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
442
|
+
// contract would perform, including setting senderForTags.
|
|
443
|
+
senderForTags: from,
|
|
444
|
+
simulator,
|
|
445
|
+
txResolver: this.stateMachine.txResolver,
|
|
446
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
447
|
+
hooks: composeHooks({
|
|
448
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(isStaticCall ? 'private view' : 'private', authorizedUtilityCallTargets),
|
|
449
|
+
resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies)
|
|
450
|
+
}),
|
|
451
|
+
transientArrayService
|
|
452
|
+
});
|
|
453
|
+
// 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.
|
|
454
|
+
let result;
|
|
455
|
+
let executionResult;
|
|
456
|
+
try {
|
|
457
|
+
executionResult = await executePrivateFunction(simulator, privateExecutionOracle, artifact, targetContractAddress, functionSelector);
|
|
458
|
+
const publicCallRequests = collectNested([
|
|
459
|
+
executionResult
|
|
460
|
+
], (r)=>r.publicInputs.publicCallRequests.getActiveItems().map((r)=>r.inner).concat(r.publicInputs.publicTeardownCallRequest.isEmpty() ? [] : [
|
|
461
|
+
r.publicInputs.publicTeardownCallRequest
|
|
462
|
+
]));
|
|
463
|
+
const publicFunctionsCalldata = await Promise.all(publicCallRequests.map(async (r)=>{
|
|
464
|
+
const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
|
|
465
|
+
return new HashedValues(calldata, r.calldataHash);
|
|
466
|
+
}));
|
|
467
|
+
const nonceGenerator = noteCache.getNonceGenerator();
|
|
468
|
+
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
469
|
+
} catch (err) {
|
|
470
|
+
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
471
|
+
}
|
|
472
|
+
// According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
|
|
473
|
+
// the nonce generator for the note hashes.
|
|
474
|
+
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
475
|
+
const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>anchoredContractData.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
|
|
476
|
+
const globals = makeGlobalVariables();
|
|
477
|
+
globals.blockNumber = blockNumber;
|
|
478
|
+
globals.timestamp = this.nextBlockTimestamp;
|
|
479
|
+
globals.chainId = this.chainId;
|
|
480
|
+
globals.version = this.version;
|
|
481
|
+
globals.gasFees = GasFees.empty();
|
|
482
|
+
const forkedWorldTrees = _ts_add_disposable_resource(env, await this.stateMachine.synchronizer.nativeWorldStateService.fork(), true);
|
|
483
|
+
const bindings = this.logger.getBindings();
|
|
484
|
+
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings);
|
|
485
|
+
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
486
|
+
const config = PublicSimulatorConfig.from({
|
|
487
|
+
skipFeeEnforcement: true,
|
|
488
|
+
collectDebugLogs: true,
|
|
489
|
+
collectHints: false,
|
|
490
|
+
collectStatistics: false,
|
|
491
|
+
collectCallMetadata: true
|
|
492
|
+
});
|
|
493
|
+
// The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
|
|
494
|
+
const forkId = forkedWorldTrees.getRevision().forkId;
|
|
495
|
+
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));
|
|
496
|
+
const tx = await Tx.create({
|
|
497
|
+
data: publicInputs,
|
|
498
|
+
chonkProof: ChonkProof.empty(),
|
|
499
|
+
contractClassLogFields: [],
|
|
500
|
+
publicFunctionCalldata: result.publicFunctionCalldata
|
|
501
|
+
});
|
|
502
|
+
let checkpoint;
|
|
503
|
+
if (isStaticCall) {
|
|
504
|
+
checkpoint = await ForkCheckpoint.new(forkedWorldTrees);
|
|
505
|
+
}
|
|
506
|
+
const results = await processor.process([
|
|
507
|
+
tx
|
|
508
|
+
]);
|
|
509
|
+
const [processedTx] = results[0];
|
|
510
|
+
const failedTxs = results[1];
|
|
511
|
+
if (failedTxs.length !== 0) {
|
|
512
|
+
throw new Error(`Public execution has failed: ${failedTxs[0].error}`);
|
|
513
|
+
} else if (!processedTx.revertCode.isOK()) {
|
|
514
|
+
if (processedTx.revertReason) {
|
|
515
|
+
try {
|
|
516
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, await this.stateMachine.anchorBlockStore.getBlockHeader(), this.logger);
|
|
517
|
+
// eslint-disable-next-line no-empty
|
|
518
|
+
} catch {}
|
|
519
|
+
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
520
|
+
} else {
|
|
521
|
+
throw new Error('Contract execution has reverted');
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
// Walk the nested private-call tree and collect every offchain effect the transaction emitted.
|
|
525
|
+
// PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
|
|
526
|
+
// `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
|
|
527
|
+
// we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
|
|
528
|
+
const offchainEffects = collectNested([
|
|
385
529
|
executionResult
|
|
386
|
-
], (r)=>r.
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
const nonceGenerator = noteCache.getNonceGenerator();
|
|
394
|
-
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
395
|
-
} catch (err) {
|
|
396
|
-
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
397
|
-
}
|
|
398
|
-
// According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
|
|
399
|
-
// the nonce generator for the note hashes.
|
|
400
|
-
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
401
|
-
const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>anchoredContractData.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
|
|
402
|
-
const globals = makeGlobalVariables();
|
|
403
|
-
globals.blockNumber = blockNumber;
|
|
404
|
-
globals.timestamp = this.nextBlockTimestamp;
|
|
405
|
-
globals.chainId = this.chainId;
|
|
406
|
-
globals.version = this.version;
|
|
407
|
-
globals.gasFees = GasFees.empty();
|
|
408
|
-
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
409
|
-
const bindings = this.logger.getBindings();
|
|
410
|
-
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings);
|
|
411
|
-
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
412
|
-
const config = PublicSimulatorConfig.from({
|
|
413
|
-
skipFeeEnforcement: true,
|
|
414
|
-
collectDebugLogs: true,
|
|
415
|
-
collectHints: false,
|
|
416
|
-
collectStatistics: false,
|
|
417
|
-
collectCallMetadata: true
|
|
418
|
-
});
|
|
419
|
-
const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings), new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings));
|
|
420
|
-
const tx = await Tx.create({
|
|
421
|
-
data: publicInputs,
|
|
422
|
-
chonkProof: ChonkProof.empty(),
|
|
423
|
-
contractClassLogFields: [],
|
|
424
|
-
publicFunctionCalldata: result.publicFunctionCalldata
|
|
425
|
-
});
|
|
426
|
-
let checkpoint;
|
|
427
|
-
if (isStaticCall) {
|
|
428
|
-
checkpoint = await ForkCheckpoint.new(forkedWorldTrees);
|
|
429
|
-
}
|
|
430
|
-
const results = await processor.process([
|
|
431
|
-
tx
|
|
432
|
-
]);
|
|
433
|
-
const [processedTx] = results[0];
|
|
434
|
-
const failedTxs = results[1];
|
|
435
|
-
if (failedTxs.length !== 0) {
|
|
436
|
-
throw new Error(`Public execution has failed: ${failedTxs[0].error}`);
|
|
437
|
-
} else if (!processedTx.revertCode.isOK()) {
|
|
438
|
-
if (processedTx.revertReason) {
|
|
439
|
-
try {
|
|
440
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, await this.stateMachine.anchorBlockStore.getBlockHeader(), this.logger);
|
|
441
|
-
// eslint-disable-next-line no-empty
|
|
442
|
-
} catch {}
|
|
443
|
-
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
444
|
-
} else {
|
|
445
|
-
throw new Error('Contract execution has reverted');
|
|
530
|
+
], (r)=>r.offchainEffects.map((e)=>e.data));
|
|
531
|
+
if (isStaticCall) {
|
|
532
|
+
await checkpoint.revert();
|
|
533
|
+
return {
|
|
534
|
+
returnValues: executionResult.returnValues ?? [],
|
|
535
|
+
offchainEffects
|
|
536
|
+
};
|
|
446
537
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
await
|
|
457
|
-
|
|
538
|
+
const txEffect = TxEffect.empty();
|
|
539
|
+
txEffect.noteHashes = processedTx.txEffect.noteHashes;
|
|
540
|
+
txEffect.nullifiers = processedTx.txEffect.nullifiers;
|
|
541
|
+
txEffect.privateLogs = processedTx.txEffect.privateLogs;
|
|
542
|
+
txEffect.publicLogs = processedTx.txEffect.publicLogs;
|
|
543
|
+
txEffect.publicDataWrites = processedTx.txEffect.publicDataWrites;
|
|
544
|
+
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
545
|
+
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
546
|
+
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
547
|
+
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [
|
|
548
|
+
txEffect
|
|
549
|
+
]);
|
|
550
|
+
await this.stateMachine.handleL2Block(l2Block);
|
|
458
551
|
return {
|
|
459
552
|
returnValues: executionResult.returnValues ?? [],
|
|
460
553
|
offchainEffects
|
|
461
554
|
};
|
|
555
|
+
} catch (e) {
|
|
556
|
+
env.error = e;
|
|
557
|
+
env.hasError = true;
|
|
558
|
+
} finally{
|
|
559
|
+
const result = _ts_dispose_resources(env);
|
|
560
|
+
if (result) await result;
|
|
462
561
|
}
|
|
463
|
-
const txEffect = TxEffect.empty();
|
|
464
|
-
txEffect.noteHashes = processedTx.txEffect.noteHashes;
|
|
465
|
-
txEffect.nullifiers = processedTx.txEffect.nullifiers;
|
|
466
|
-
txEffect.privateLogs = processedTx.txEffect.privateLogs;
|
|
467
|
-
txEffect.publicLogs = processedTx.txEffect.publicLogs;
|
|
468
|
-
txEffect.publicDataWrites = processedTx.txEffect.publicDataWrites;
|
|
469
|
-
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
470
|
-
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
471
|
-
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
472
|
-
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [
|
|
473
|
-
txEffect
|
|
474
|
-
]);
|
|
475
|
-
await this.stateMachine.handleL2Block(l2Block);
|
|
476
|
-
await forkedWorldTrees.close();
|
|
477
|
-
return {
|
|
478
|
-
returnValues: executionResult.returnValues ?? [],
|
|
479
|
-
offchainEffects
|
|
480
|
-
};
|
|
481
562
|
}
|
|
482
563
|
async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall, gasSettings) {
|
|
483
|
-
const
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
} else if (!processedTx.revertCode.isOK()) {
|
|
542
|
-
if (processedTx.revertReason) {
|
|
543
|
-
try {
|
|
544
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader, this.logger);
|
|
545
|
-
// eslint-disable-next-line no-empty
|
|
546
|
-
} catch {}
|
|
547
|
-
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
548
|
-
} else {
|
|
549
|
-
throw new Error('Contract execution has reverted');
|
|
564
|
+
const env = {
|
|
565
|
+
stack: [],
|
|
566
|
+
error: void 0,
|
|
567
|
+
hasError: false
|
|
568
|
+
};
|
|
569
|
+
try {
|
|
570
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
571
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
|
|
572
|
+
this.logger.verbose(`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
|
|
573
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
574
|
+
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
575
|
+
const calldataHash = await computeCalldataHash(calldata);
|
|
576
|
+
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
577
|
+
const globals = makeGlobalVariables();
|
|
578
|
+
globals.blockNumber = blockNumber;
|
|
579
|
+
globals.timestamp = this.nextBlockTimestamp;
|
|
580
|
+
globals.chainId = this.chainId;
|
|
581
|
+
globals.version = this.version;
|
|
582
|
+
globals.gasFees = GasFees.empty();
|
|
583
|
+
const forkedWorldTrees = _ts_add_disposable_resource(env, await this.stateMachine.synchronizer.nativeWorldStateService.fork(), true);
|
|
584
|
+
const bindings2 = this.logger.getBindings();
|
|
585
|
+
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings2);
|
|
586
|
+
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
587
|
+
const config = PublicSimulatorConfig.from({
|
|
588
|
+
skipFeeEnforcement: true,
|
|
589
|
+
collectDebugLogs: true,
|
|
590
|
+
collectHints: false,
|
|
591
|
+
collectStatistics: false,
|
|
592
|
+
collectCallMetadata: true
|
|
593
|
+
});
|
|
594
|
+
// The AVM simulator reads this fork's contracts DB, scoped by fork id, for each simulation.
|
|
595
|
+
const forkId2 = forkedWorldTrees.getRevision().forkId;
|
|
596
|
+
const simulator = new PublicTxSimulator(this.stateMachine.synchronizer.avmSimulator, globals, contractsDB, forkId2, config, bindings2);
|
|
597
|
+
const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings2));
|
|
598
|
+
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
599
|
+
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
600
|
+
// side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
|
|
601
|
+
// unique.
|
|
602
|
+
const nonRevertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
603
|
+
nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
|
|
604
|
+
// The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
|
|
605
|
+
// may require producing reverts.
|
|
606
|
+
const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
607
|
+
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from ?? AztecAddress.NULL_MSG_SENDER, targetContractAddress, isStaticCall, calldataHash);
|
|
608
|
+
const inputsForPublic = new PartialPrivateTailPublicInputsForPublic(nonRevertibleAccumulatedData, revertibleAccumulatedData, PublicCallRequest.empty());
|
|
609
|
+
const constantData = new TxConstantData(anchorBlockHeader, txContext, Fr.zero(), Fr.zero());
|
|
610
|
+
const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*expirationTimestamp=*/ 0n, inputsForPublic, undefined);
|
|
611
|
+
const tx = await Tx.create({
|
|
612
|
+
data: txData,
|
|
613
|
+
chonkProof: ChonkProof.empty(),
|
|
614
|
+
contractClassLogFields: [],
|
|
615
|
+
publicFunctionCalldata: [
|
|
616
|
+
calldataHashedValues
|
|
617
|
+
]
|
|
618
|
+
});
|
|
619
|
+
let checkpoint;
|
|
620
|
+
if (isStaticCall) {
|
|
621
|
+
checkpoint = await ForkCheckpoint.new(forkedWorldTrees);
|
|
550
622
|
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
623
|
+
const results = await processor.process([
|
|
624
|
+
tx
|
|
625
|
+
]);
|
|
626
|
+
const [processedTx] = results[0];
|
|
627
|
+
const failedTxs = results[1];
|
|
628
|
+
if (failedTxs.length !== 0) {
|
|
629
|
+
throw new Error(`Public execution has failed: ${failedTxs[0].error}`);
|
|
630
|
+
} else if (!processedTx.revertCode.isOK()) {
|
|
631
|
+
if (processedTx.revertReason) {
|
|
632
|
+
try {
|
|
633
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader, this.logger);
|
|
634
|
+
// eslint-disable-next-line no-empty
|
|
635
|
+
} catch {}
|
|
636
|
+
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
637
|
+
} else {
|
|
638
|
+
throw new Error('Contract execution has reverted');
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
const returnValues = results[3][0].values;
|
|
642
|
+
if (isStaticCall) {
|
|
643
|
+
await checkpoint.revert();
|
|
644
|
+
return returnValues ?? [];
|
|
645
|
+
}
|
|
646
|
+
const txEffect = TxEffect.empty();
|
|
647
|
+
txEffect.noteHashes = processedTx.txEffect.noteHashes;
|
|
648
|
+
txEffect.nullifiers = processedTx.txEffect.nullifiers;
|
|
649
|
+
txEffect.privateLogs = processedTx.txEffect.privateLogs;
|
|
650
|
+
txEffect.publicLogs = processedTx.txEffect.publicLogs;
|
|
651
|
+
txEffect.publicDataWrites = processedTx.txEffect.publicDataWrites;
|
|
652
|
+
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
653
|
+
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
654
|
+
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
655
|
+
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [
|
|
656
|
+
txEffect
|
|
657
|
+
]);
|
|
658
|
+
await this.stateMachine.handleL2Block(l2Block);
|
|
556
659
|
return returnValues ?? [];
|
|
660
|
+
} catch (e) {
|
|
661
|
+
env.error = e;
|
|
662
|
+
env.hasError = true;
|
|
663
|
+
} finally{
|
|
664
|
+
const result = _ts_dispose_resources(env);
|
|
665
|
+
if (result) await result;
|
|
557
666
|
}
|
|
558
|
-
const txEffect = TxEffect.empty();
|
|
559
|
-
txEffect.noteHashes = processedTx.txEffect.noteHashes;
|
|
560
|
-
txEffect.nullifiers = processedTx.txEffect.nullifiers;
|
|
561
|
-
txEffect.privateLogs = processedTx.txEffect.privateLogs;
|
|
562
|
-
txEffect.publicLogs = processedTx.txEffect.publicLogs;
|
|
563
|
-
txEffect.publicDataWrites = processedTx.txEffect.publicDataWrites;
|
|
564
|
-
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
565
|
-
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
566
|
-
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
567
|
-
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [
|
|
568
|
-
txEffect
|
|
569
|
-
]);
|
|
570
|
-
await this.stateMachine.handleL2Block(l2Block);
|
|
571
|
-
await forkedWorldTrees.close();
|
|
572
|
-
return returnValues ?? [];
|
|
573
667
|
}
|
|
574
668
|
async executeUtilityFunction(from, targetContractAddress, functionSelector, args, jobId, authorizedUtilityCallTargets) {
|
|
575
669
|
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
@@ -592,8 +686,7 @@ export class TXEOracleTopLevelContext {
|
|
|
592
686
|
type: FunctionType.UTILITY,
|
|
593
687
|
hideMsgSender: false,
|
|
594
688
|
isStatic: false,
|
|
595
|
-
args
|
|
596
|
-
returnTypes: []
|
|
689
|
+
args
|
|
597
690
|
});
|
|
598
691
|
return this.executeUtilityCall(call, {
|
|
599
692
|
from,
|
|
@@ -621,8 +714,7 @@ export class TXEOracleTopLevelContext {
|
|
|
621
714
|
const utilityExecutor = async (syncCall, execScopes)=>{
|
|
622
715
|
await this.executeUtilityCall(syncCall, {
|
|
623
716
|
scopes: execScopes,
|
|
624
|
-
jobId
|
|
625
|
-
authorizedUtilityCallTargets
|
|
717
|
+
jobId
|
|
626
718
|
});
|
|
627
719
|
};
|
|
628
720
|
const oracle = new UtilityExecutionOracle({
|
|
@@ -651,10 +743,10 @@ export class TXEOracleTopLevelContext {
|
|
|
651
743
|
jobId,
|
|
652
744
|
scopes,
|
|
653
745
|
simulator,
|
|
654
|
-
utilityExecutor,
|
|
655
746
|
hooks: composeHooks({
|
|
656
747
|
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets)
|
|
657
748
|
}),
|
|
749
|
+
utilityExecutor,
|
|
658
750
|
// Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
|
|
659
751
|
transientArrayService: new TransientArrayService()
|
|
660
752
|
});
|
|
@@ -675,17 +767,21 @@ export class TXEOracleTopLevelContext {
|
|
|
675
767
|
}
|
|
676
768
|
close() {
|
|
677
769
|
this.logger.debug('Exiting Top Level Context');
|
|
678
|
-
return
|
|
679
|
-
this.nextBlockTimestamp,
|
|
680
|
-
this.authwits,
|
|
681
|
-
this.taggingSecretStrategies
|
|
682
|
-
|
|
770
|
+
return {
|
|
771
|
+
nextBlockTimestamp: this.nextBlockTimestamp,
|
|
772
|
+
authwits: this.authwits,
|
|
773
|
+
taggingSecretStrategies: this.taggingSecretStrategies,
|
|
774
|
+
authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets
|
|
775
|
+
};
|
|
683
776
|
}
|
|
684
777
|
async getLastBlockNumber() {
|
|
685
778
|
const block = await this.stateMachine.node.getBlock('latest');
|
|
686
779
|
return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
687
780
|
}
|
|
688
781
|
buildAuthorizeUtilityCallHook(callerContext, authorizedTargets) {
|
|
782
|
+
if (this.authorizeAllUtilityCallTargets) {
|
|
783
|
+
return authorizeAllUtilityCallsHook;
|
|
784
|
+
}
|
|
689
785
|
if (authorizedTargets.length === 0) {
|
|
690
786
|
return undefined;
|
|
691
787
|
}
|
|
@@ -694,3 +790,10 @@ export class TXEOracleTopLevelContext {
|
|
|
694
790
|
});
|
|
695
791
|
}
|
|
696
792
|
}
|
|
793
|
+
/**
|
|
794
|
+
* An `authorizeUtilityCall` hook that authorizes every cross-contract utility call.
|
|
795
|
+
*
|
|
796
|
+
* Backs the `aztec_txe_setAuthorizeAllUtilityCallTargets` oracle.
|
|
797
|
+
*/ export const authorizeAllUtilityCallsHook = ()=>Promise.resolve({
|
|
798
|
+
authorized: true
|
|
799
|
+
});
|