@aztec/txe 0.0.1-commit.993d240 → 0.0.1-commit.9a89641
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-WLOZKTR6.js +3 -0
- package/dest/ContractInstanceRegistry-WLOZKTR6.js.map +7 -0
- 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-QG5H33ZZ.js.map +7 -0
- 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 +9 -19
- package/dest/bin/index.js +1 -1
- package/dest/bin/oracle_test_server.d.ts +3 -0
- package/dest/bin/oracle_test_server.d.ts.map +1 -0
- package/dest/bin/oracle_test_server.js +41 -0
- package/dest/chunk-32UHX7YY.js +3 -0
- package/dest/{chunk-DF6RMOC6.js → chunk-RVEPNDEP.js} +2 -2
- package/dest/{chunk-DF6RMOC6.js.map → chunk-RVEPNDEP.js.map} +3 -3
- package/dest/chunk-XWIMXLKD.js +258 -0
- package/dest/chunk-XWIMXLKD.js.map +7 -0
- package/dest/constants.d.ts +3 -1
- package/dest/constants.d.ts.map +1 -1
- package/dest/constants.js +5 -2
- package/dest/dispatcher_pool.d.ts +2 -2
- package/dest/dispatcher_pool.d.ts.map +1 -1
- package/dest/dispatcher_pool.js +5 -3
- package/dest/index.d.ts +6 -143
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +12 -169
- package/dest/metafile.json +10267 -9581
- package/dest/oracle/interfaces.d.ts +38 -11
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/tagging_secret_strategy.d.ts +12 -0
- package/dest/oracle/tagging_secret_strategy.d.ts.map +1 -0
- package/dest/oracle/tagging_secret_strategy.js +12 -0
- package/dest/oracle/test-resolver/default_fixtures.d.ts +16 -0
- package/dest/oracle/test-resolver/default_fixtures.d.ts.map +1 -0
- package/dest/oracle/test-resolver/default_fixtures.js +200 -0
- package/dest/oracle/test-resolver/index.d.ts +9 -0
- package/dest/oracle/test-resolver/index.d.ts.map +1 -0
- package/dest/oracle/test-resolver/index.js +32 -0
- package/dest/oracle/test-resolver/resolver.d.ts +48 -0
- package/dest/oracle/test-resolver/resolver.d.ts.map +1 -0
- package/dest/oracle/test-resolver/resolver.js +181 -0
- package/dest/oracle/txe_oracle_public_context.d.ts +25 -6
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +34 -1
- package/dest/oracle/txe_oracle_registry.d.ts +172 -0
- package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
- package/dest/oracle/txe_oracle_registry.js +767 -0
- package/dest/oracle/txe_oracle_top_level_context.d.ts +39 -14
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +489 -289
- package/dest/{txe_oracle_version.d.ts → oracle/txe_oracle_version.d.ts} +5 -5
- package/dest/oracle/txe_oracle_version.d.ts.map +1 -0
- package/dest/{txe_oracle_version.js → oracle/txe_oracle_version.js} +4 -4
- package/dest/rpc_translator.d.ts +116 -284
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +809 -860
- package/dest/server.bundle.js +1 -1
- package/dest/state_machine/archiver.d.ts +3 -2
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +9 -3
- package/dest/state_machine/dummy_p2p_client.d.ts +5 -2
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +9 -0
- package/dest/state_machine/global_variable_builder.d.ts +3 -4
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +0 -3
- package/dest/state_machine/index.d.ts +8 -6
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +41 -19
- package/dest/state_machine/mock_epoch_cache.d.ts +2 -3
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +3 -6
- package/dest/state_machine/synchronizer.d.ts +10 -2
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +18 -5
- package/dest/txe_session.d.ts +43 -28
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +183 -47
- package/dest/utils/block_creation.d.ts +2 -2
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +2 -2
- package/dest/utils/encoding.d.ts +8 -5
- package/dest/utils/encoding.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.d.ts +1 -1
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +0 -1
- package/dest/utils/txe_artifact_resolver.d.ts +37 -0
- package/dest/utils/txe_artifact_resolver.d.ts.map +1 -0
- package/dest/utils/txe_artifact_resolver.js +161 -0
- package/dest/utils/txe_public_contract_data_source.d.ts +1 -1
- package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -1
- package/dest/utils/txe_public_contract_data_source.js +7 -4
- package/dest/worker.bundle.js +1 -1
- package/package.json +18 -17
- package/src/bin/check_txe_oracle_version.ts +11 -17
- package/src/bin/oracle_test_server.ts +51 -0
- package/src/constants.ts +6 -2
- package/src/dispatcher_pool.ts +4 -3
- package/src/index.ts +21 -198
- package/src/oracle/interfaces.ts +35 -9
- package/src/oracle/tagging_secret_strategy.ts +25 -0
- package/src/oracle/test-resolver/default_fixtures.ts +271 -0
- package/src/oracle/test-resolver/index.ts +44 -0
- package/src/oracle/test-resolver/resolver.ts +245 -0
- package/src/oracle/txe_oracle_public_context.ts +36 -4
- package/src/oracle/txe_oracle_registry.ts +556 -0
- package/src/oracle/txe_oracle_top_level_context.ts +249 -66
- package/src/{txe_oracle_version.ts → oracle/txe_oracle_version.ts} +4 -4
- package/src/rpc_translator.ts +850 -1065
- package/src/state_machine/archiver.ts +9 -3
- package/src/state_machine/dummy_p2p_client.ts +13 -0
- package/src/state_machine/global_variable_builder.ts +2 -16
- package/src/state_machine/index.ts +50 -34
- package/src/state_machine/mock_epoch_cache.ts +4 -8
- package/src/state_machine/synchronizer.ts +26 -5
- package/src/txe_session.ts +325 -56
- package/src/utils/block_creation.ts +2 -1
- package/src/utils/tx_effect_creation.ts +0 -2
- package/src/utils/txe_artifact_resolver.ts +217 -0
- package/src/utils/txe_public_contract_data_source.ts +6 -4
- package/dest/ContractClassRegistry-KKNT527R.js +0 -3
- package/dest/ContractClassRegistry-KKNT527R.js.map +0 -7
- package/dest/ContractInstanceRegistry-GSKBNL3Q.js +0 -3
- package/dest/ContractInstanceRegistry-GSKBNL3Q.js.map +0 -7
- package/dest/FeeJuice-GUJ5O6GB.js +0 -3
- package/dest/FeeJuice-GUJ5O6GB.js.map +0 -7
- package/dest/MultiCallEntrypoint-ZQPCKVKL.js +0 -3
- package/dest/MultiCallEntrypoint-ZQPCKVKL.js.map +0 -7
- package/dest/SchnorrAccount-QIXE5DXA.js +0 -3
- package/dest/SchnorrAccount-QIXE5DXA.js.map +0 -7
- package/dest/chunk-BJVAAXNA.js +0 -3
- package/dest/chunk-PPJTNNUG.js +0 -265
- package/dest/chunk-PPJTNNUG.js.map +0 -7
- package/dest/txe_oracle_version.d.ts.map +0 -1
- /package/dest/{chunk-BJVAAXNA.js.map → chunk-32UHX7YY.js.map} +0 -0
|
@@ -1,13 +1,78 @@
|
|
|
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';
|
|
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_MAJOR, composeHooks, enrichPublicSimulationError } from '@aztec/pxe/server';
|
|
8
|
-
import { ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache,
|
|
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 {
|
|
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';
|
|
@@ -16,15 +81,18 @@ import { computePartialAddress } from '@aztec/stdlib/contract';
|
|
|
16
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';
|
|
19
|
-
import { hashPublicKey } from '@aztec/stdlib/keys';
|
|
84
|
+
import { deriveKeys, hashPublicKey } from '@aztec/stdlib/keys';
|
|
85
|
+
import { AppTaggingSecretKind } from '@aztec/stdlib/logs';
|
|
86
|
+
import { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
|
|
20
87
|
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
21
88
|
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
22
89
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
23
90
|
import { CallContext, HashedValues, PrivateExecutionResult, Tx, TxConstantData, TxContext, TxEffect, TxHash, collectNested } from '@aztec/stdlib/tx';
|
|
24
91
|
import { ForkCheckpoint } from '@aztec/world-state/native';
|
|
25
|
-
import { DEFAULT_ADDRESS } from '../constants.js';
|
|
92
|
+
import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
|
|
26
93
|
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
27
94
|
import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
|
|
95
|
+
import { makeResolveTaggingSecretStrategyHook } from './tagging_secret_strategy.js';
|
|
28
96
|
export class TXEOracleTopLevelContext {
|
|
29
97
|
stateMachine;
|
|
30
98
|
contractStore;
|
|
@@ -34,17 +102,23 @@ export class TXEOracleTopLevelContext {
|
|
|
34
102
|
accountStore;
|
|
35
103
|
senderTaggingStore;
|
|
36
104
|
recipientTaggingStore;
|
|
37
|
-
|
|
105
|
+
taggingSecretSourcesStore;
|
|
38
106
|
capsuleStore;
|
|
107
|
+
factStore;
|
|
39
108
|
privateEventStore;
|
|
40
109
|
nextBlockTimestamp;
|
|
41
110
|
version;
|
|
42
111
|
chainId;
|
|
43
112
|
authwits;
|
|
113
|
+
taggingSecretStrategies;
|
|
114
|
+
authorizeAllUtilityCallTargets;
|
|
115
|
+
artifactResolver;
|
|
116
|
+
rootPath;
|
|
117
|
+
packageName;
|
|
44
118
|
isMisc;
|
|
45
119
|
isTxe;
|
|
46
120
|
logger;
|
|
47
|
-
constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore,
|
|
121
|
+
constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, taggingSecretSourcesStore, capsuleStore, factStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits, taggingSecretStrategies, authorizeAllUtilityCallTargets, artifactResolver, rootPath, packageName){
|
|
48
122
|
this.stateMachine = stateMachine;
|
|
49
123
|
this.contractStore = contractStore;
|
|
50
124
|
this.noteStore = noteStore;
|
|
@@ -53,13 +127,19 @@ export class TXEOracleTopLevelContext {
|
|
|
53
127
|
this.accountStore = accountStore;
|
|
54
128
|
this.senderTaggingStore = senderTaggingStore;
|
|
55
129
|
this.recipientTaggingStore = recipientTaggingStore;
|
|
56
|
-
this.
|
|
130
|
+
this.taggingSecretSourcesStore = taggingSecretSourcesStore;
|
|
57
131
|
this.capsuleStore = capsuleStore;
|
|
132
|
+
this.factStore = factStore;
|
|
58
133
|
this.privateEventStore = privateEventStore;
|
|
59
134
|
this.nextBlockTimestamp = nextBlockTimestamp;
|
|
60
135
|
this.version = version;
|
|
61
136
|
this.chainId = chainId;
|
|
62
137
|
this.authwits = authwits;
|
|
138
|
+
this.taggingSecretStrategies = taggingSecretStrategies;
|
|
139
|
+
this.authorizeAllUtilityCallTargets = authorizeAllUtilityCallTargets;
|
|
140
|
+
this.artifactResolver = artifactResolver;
|
|
141
|
+
this.rootPath = rootPath;
|
|
142
|
+
this.packageName = packageName;
|
|
63
143
|
this.isMisc = true;
|
|
64
144
|
this.isTxe = true;
|
|
65
145
|
this.logger = createLogger('txe:top_level_context');
|
|
@@ -86,7 +166,7 @@ export class TXEOracleTopLevelContext {
|
|
|
86
166
|
return Fr.random();
|
|
87
167
|
}
|
|
88
168
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
89
|
-
log(level, message, fields) {
|
|
169
|
+
log(level, message, _fieldsSize, fields) {
|
|
90
170
|
if (!LogLevels[level]) {
|
|
91
171
|
throw new Error(`Invalid log level: ${level}`);
|
|
92
172
|
}
|
|
@@ -136,13 +216,16 @@ export class TXEOracleTopLevelContext {
|
|
|
136
216
|
}
|
|
137
217
|
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
138
218
|
await this.stateMachine.contractSyncService.ensureContractSynced(contractAddress, null, async (call, execScopes)=>{
|
|
139
|
-
await this.executeUtilityCall(call,
|
|
219
|
+
await this.executeUtilityCall(call, {
|
|
220
|
+
scopes: execScopes,
|
|
221
|
+
jobId
|
|
222
|
+
});
|
|
140
223
|
}, blockHeader, jobId, [
|
|
141
224
|
scope
|
|
142
225
|
]);
|
|
143
226
|
}
|
|
144
227
|
async getPrivateEvents(selector, contractAddress, scope) {
|
|
145
|
-
|
|
228
|
+
const events = (await this.privateEventStore.getPrivateEvents(selector, {
|
|
146
229
|
contractAddress,
|
|
147
230
|
scopes: [
|
|
148
231
|
scope
|
|
@@ -150,6 +233,13 @@ export class TXEOracleTopLevelContext {
|
|
|
150
233
|
fromBlock: 0,
|
|
151
234
|
toBlock: await this.getLastBlockNumber() + 1
|
|
152
235
|
})).map((e)=>e.packedEvent);
|
|
236
|
+
if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
|
|
237
|
+
throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
|
|
238
|
+
}
|
|
239
|
+
if (events.some((e)=>e.length > MAX_PRIVATE_EVENT_LEN)) {
|
|
240
|
+
throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
|
|
241
|
+
}
|
|
242
|
+
return events;
|
|
153
243
|
}
|
|
154
244
|
async advanceBlocksBy(blocks) {
|
|
155
245
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
@@ -162,9 +252,19 @@ export class TXEOracleTopLevelContext {
|
|
|
162
252
|
this.nextBlockTimestamp += duration;
|
|
163
253
|
}
|
|
164
254
|
deploymentNullifier(address) {
|
|
165
|
-
return siloNullifier(AztecAddress.
|
|
255
|
+
return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
|
|
166
256
|
}
|
|
167
|
-
async deploy(
|
|
257
|
+
async deploy(contractPath, initializer, args, secret, salt, deployer) {
|
|
258
|
+
const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
|
|
259
|
+
rootPath: this.rootPath,
|
|
260
|
+
packageName: this.packageName,
|
|
261
|
+
contractPath,
|
|
262
|
+
initializer,
|
|
263
|
+
args,
|
|
264
|
+
secret,
|
|
265
|
+
salt,
|
|
266
|
+
deployer
|
|
267
|
+
});
|
|
168
268
|
// Emit deployment nullifier
|
|
169
269
|
await this.mineBlock({
|
|
170
270
|
nullifiers: [
|
|
@@ -172,12 +272,13 @@ export class TXEOracleTopLevelContext {
|
|
|
172
272
|
]
|
|
173
273
|
});
|
|
174
274
|
if (!secret.equals(Fr.ZERO)) {
|
|
175
|
-
await this.
|
|
275
|
+
await this.registerContractAndAddAccount(artifact, instance, secret);
|
|
176
276
|
} else {
|
|
177
277
|
await this.contractStore.addContractInstance(instance);
|
|
178
278
|
await this.contractStore.addContractArtifact(artifact);
|
|
179
279
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
180
280
|
}
|
|
281
|
+
return CONTRACT_INSTANCE.serialization.fn(instance).flat();
|
|
181
282
|
}
|
|
182
283
|
/**
|
|
183
284
|
* Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
|
|
@@ -186,20 +287,23 @@ export class TXEOracleTopLevelContext {
|
|
|
186
287
|
nullifiers: await Promise.all(addresses.map((address)=>this.deploymentNullifier(address)))
|
|
187
288
|
});
|
|
188
289
|
}
|
|
189
|
-
async addAccount(
|
|
290
|
+
async addAccount(secret) {
|
|
291
|
+
const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
|
|
292
|
+
return this.registerContractAndAddAccount(artifact, instance, secret);
|
|
293
|
+
}
|
|
294
|
+
async registerContractAndAddAccount(artifact, instance, secret) {
|
|
190
295
|
const partialAddress = await computePartialAddress(instance);
|
|
191
296
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
192
297
|
await this.contractStore.addContractInstance(instance);
|
|
193
298
|
await this.contractStore.addContractArtifact(artifact);
|
|
194
|
-
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
299
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
195
300
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
196
301
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
197
302
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
198
303
|
return completeAddress;
|
|
199
304
|
}
|
|
200
|
-
async createAccount(secret) {
|
|
201
|
-
|
|
202
|
-
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
305
|
+
async createAccount(secret, partialAddress) {
|
|
306
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
203
307
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
204
308
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
205
309
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -214,6 +318,32 @@ export class TXEOracleTopLevelContext {
|
|
|
214
318
|
const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
|
|
215
319
|
this.authwits.set(authWitness.requestHash.toString(), authWitness);
|
|
216
320
|
}
|
|
321
|
+
setTaggingSecretStrategies(unconstrainedStrategy, constrainedStrategy) {
|
|
322
|
+
const apply = (mode, strategy)=>{
|
|
323
|
+
if (strategy.isSome()) {
|
|
324
|
+
this.taggingSecretStrategies.set(mode, strategy.value);
|
|
325
|
+
} else {
|
|
326
|
+
this.taggingSecretStrategies.delete(mode);
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
apply(AppTaggingSecretKind.UNCONSTRAINED, unconstrainedStrategy);
|
|
330
|
+
apply(AppTaggingSecretKind.CONSTRAINED, constrainedStrategy);
|
|
331
|
+
}
|
|
332
|
+
setAuthorizeAllUtilityCallTargets(authorizeAll) {
|
|
333
|
+
this.authorizeAllUtilityCallTargets = authorizeAll;
|
|
334
|
+
}
|
|
335
|
+
async sendL1ToL2Message(content, secretHash, sender, recipient) {
|
|
336
|
+
// Messages are appended to the tree, so the next free slot is simply the current tree size.
|
|
337
|
+
const { size } = await this.stateMachine.synchronizer.getCommitted().getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
|
|
338
|
+
const leafIndex = new Fr(size);
|
|
339
|
+
const message = new L1ToL2Message(new L1Actor(sender, this.chainId.toNumber()), new L2Actor(recipient, this.version.toNumber()), content, secretHash, leafIndex);
|
|
340
|
+
await this.mineBlock({
|
|
341
|
+
l1ToL2Messages: [
|
|
342
|
+
message.hash()
|
|
343
|
+
]
|
|
344
|
+
});
|
|
345
|
+
return leafIndex;
|
|
346
|
+
}
|
|
217
347
|
async mineBlock(options = {}) {
|
|
218
348
|
const blockNumber = await this.getNextBlockNumber();
|
|
219
349
|
const txEffect = TxEffect.empty();
|
|
@@ -223,7 +353,7 @@ export class TXEOracleTopLevelContext {
|
|
|
223
353
|
];
|
|
224
354
|
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
225
355
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
226
|
-
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
356
|
+
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
|
|
227
357
|
const globals = makeGlobalVariables(undefined, {
|
|
228
358
|
blockNumber,
|
|
229
359
|
timestamp: this.nextBlockTimestamp,
|
|
@@ -235,280 +365,319 @@ export class TXEOracleTopLevelContext {
|
|
|
235
365
|
]);
|
|
236
366
|
await forkedWorldTrees.close();
|
|
237
367
|
this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
|
|
238
|
-
await this.stateMachine.handleL2Block(block);
|
|
368
|
+
await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
|
|
239
369
|
}
|
|
240
370
|
async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, additionalScopes = [], jobId, authorizedUtilityCallTargets, gasSettings) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
throw new Error(message);
|
|
246
|
-
}
|
|
247
|
-
const scopes = from === undefined ? additionalScopes : [
|
|
248
|
-
from,
|
|
249
|
-
...additionalScopes
|
|
250
|
-
];
|
|
251
|
-
// Sync notes before executing private function to discover notes from previous transactions
|
|
252
|
-
const utilityExecutor = async (call, execScopes)=>{
|
|
253
|
-
await this.executeUtilityCall(call, execScopes, jobId);
|
|
371
|
+
const env = {
|
|
372
|
+
stack: [],
|
|
373
|
+
error: void 0,
|
|
374
|
+
hasError: false
|
|
254
375
|
};
|
|
255
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
256
|
-
await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, scopes);
|
|
257
|
-
const blockNumber = await this.getNextBlockNumber();
|
|
258
|
-
const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
|
|
259
|
-
const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
|
|
260
|
-
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
261
|
-
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
262
|
-
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
263
|
-
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
264
|
-
// Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
|
|
265
|
-
// marking all side effects as revertible.
|
|
266
|
-
const minRevertibleSideEffectCounter = 1;
|
|
267
|
-
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
268
|
-
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
269
|
-
const simulator = new WASMSimulator();
|
|
270
|
-
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
271
|
-
argsHash,
|
|
272
|
-
txContext,
|
|
273
|
-
callContext,
|
|
274
|
-
anchorBlockHeader: blockHeader,
|
|
275
|
-
utilityExecutor,
|
|
276
|
-
authWitnesses: Array.from(this.authwits.values()),
|
|
277
|
-
capsules: [],
|
|
278
|
-
executionCache: HashedValuesCache.create([
|
|
279
|
-
new HashedValues(args, argsHash)
|
|
280
|
-
]),
|
|
281
|
-
noteCache,
|
|
282
|
-
taggingIndexCache,
|
|
283
|
-
contractStore: this.contractStore,
|
|
284
|
-
noteStore: this.noteStore,
|
|
285
|
-
keyStore: this.keyStore,
|
|
286
|
-
addressStore: this.addressStore,
|
|
287
|
-
aztecNode: this.stateMachine.node,
|
|
288
|
-
senderTaggingStore: this.senderTaggingStore,
|
|
289
|
-
recipientTaggingStore: this.recipientTaggingStore,
|
|
290
|
-
senderAddressBookStore: this.senderAddressBookStore,
|
|
291
|
-
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
292
|
-
privateEventStore: this.privateEventStore,
|
|
293
|
-
contractSyncService: this.stateMachine.contractSyncService,
|
|
294
|
-
jobId,
|
|
295
|
-
totalPublicCalldataCount: 0,
|
|
296
|
-
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
297
|
-
scopes,
|
|
298
|
-
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
299
|
-
// contract would perform, including setting senderForTags.
|
|
300
|
-
senderForTags: from,
|
|
301
|
-
simulator,
|
|
302
|
-
messageContextService: this.stateMachine.messageContextService,
|
|
303
|
-
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
304
|
-
hooks: composeHooks({
|
|
305
|
-
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(isStaticCall ? 'private view' : 'private', authorizedUtilityCallTargets)
|
|
306
|
-
})
|
|
307
|
-
});
|
|
308
|
-
// Note: This is a slight modification of simulator.run without any of the checks. Maybe we should modify simulator.run with a boolean value to skip checks.
|
|
309
|
-
let result;
|
|
310
|
-
let executionResult;
|
|
311
376
|
try {
|
|
312
|
-
|
|
313
|
-
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([
|
|
314
529
|
executionResult
|
|
315
|
-
], (r)=>r.
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
noteCache.finish();
|
|
323
|
-
const nonceGenerator = noteCache.getNonceGenerator();
|
|
324
|
-
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
325
|
-
} catch (err) {
|
|
326
|
-
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
327
|
-
}
|
|
328
|
-
// According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
|
|
329
|
-
// the nonce generator for the note hashes.
|
|
330
|
-
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
331
|
-
const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>this.contractStore.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
|
|
332
|
-
const globals = makeGlobalVariables();
|
|
333
|
-
globals.blockNumber = blockNumber;
|
|
334
|
-
globals.timestamp = this.nextBlockTimestamp;
|
|
335
|
-
globals.chainId = this.chainId;
|
|
336
|
-
globals.version = this.version;
|
|
337
|
-
globals.gasFees = GasFees.empty();
|
|
338
|
-
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
339
|
-
const bindings = this.logger.getBindings();
|
|
340
|
-
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore), bindings);
|
|
341
|
-
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
342
|
-
const config = PublicSimulatorConfig.from({
|
|
343
|
-
skipFeeEnforcement: true,
|
|
344
|
-
collectDebugLogs: true,
|
|
345
|
-
collectHints: false,
|
|
346
|
-
collectStatistics: false,
|
|
347
|
-
collectCallMetadata: true
|
|
348
|
-
});
|
|
349
|
-
const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings), new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings));
|
|
350
|
-
const tx = await Tx.create({
|
|
351
|
-
data: publicInputs,
|
|
352
|
-
chonkProof: ChonkProof.empty(),
|
|
353
|
-
contractClassLogFields: [],
|
|
354
|
-
publicFunctionCalldata: result.publicFunctionCalldata
|
|
355
|
-
});
|
|
356
|
-
let checkpoint;
|
|
357
|
-
if (isStaticCall) {
|
|
358
|
-
checkpoint = await ForkCheckpoint.new(forkedWorldTrees);
|
|
359
|
-
}
|
|
360
|
-
const results = await processor.process([
|
|
361
|
-
tx
|
|
362
|
-
]);
|
|
363
|
-
const [processedTx] = results[0];
|
|
364
|
-
const failedTxs = results[1];
|
|
365
|
-
if (failedTxs.length !== 0) {
|
|
366
|
-
throw new Error(`Public execution has failed: ${failedTxs[0].error}`);
|
|
367
|
-
} else if (!processedTx.revertCode.isOK()) {
|
|
368
|
-
if (processedTx.revertReason) {
|
|
369
|
-
try {
|
|
370
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
371
|
-
// eslint-disable-next-line no-empty
|
|
372
|
-
} catch {}
|
|
373
|
-
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
374
|
-
} else {
|
|
375
|
-
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
|
+
};
|
|
376
537
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
await
|
|
387
|
-
|
|
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);
|
|
388
551
|
return {
|
|
389
552
|
returnValues: executionResult.returnValues ?? [],
|
|
390
553
|
offchainEffects
|
|
391
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;
|
|
392
561
|
}
|
|
393
|
-
const txEffect = TxEffect.empty();
|
|
394
|
-
txEffect.noteHashes = processedTx.txEffect.noteHashes;
|
|
395
|
-
txEffect.nullifiers = processedTx.txEffect.nullifiers;
|
|
396
|
-
txEffect.privateLogs = processedTx.txEffect.privateLogs;
|
|
397
|
-
txEffect.publicLogs = processedTx.txEffect.publicLogs;
|
|
398
|
-
txEffect.publicDataWrites = processedTx.txEffect.publicDataWrites;
|
|
399
|
-
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
400
|
-
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
401
|
-
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
402
|
-
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [
|
|
403
|
-
txEffect
|
|
404
|
-
]);
|
|
405
|
-
await this.stateMachine.handleL2Block(l2Block);
|
|
406
|
-
await forkedWorldTrees.close();
|
|
407
|
-
return {
|
|
408
|
-
returnValues: executionResult.returnValues ?? [],
|
|
409
|
-
offchainEffects
|
|
410
|
-
};
|
|
411
562
|
}
|
|
412
563
|
async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall, gasSettings) {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
if (processedTx.revertReason) {
|
|
472
|
-
try {
|
|
473
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
474
|
-
// eslint-disable-next-line no-empty
|
|
475
|
-
} catch {}
|
|
476
|
-
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
477
|
-
} else {
|
|
478
|
-
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);
|
|
479
622
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
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);
|
|
485
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;
|
|
486
666
|
}
|
|
487
|
-
const txEffect = TxEffect.empty();
|
|
488
|
-
txEffect.noteHashes = processedTx.txEffect.noteHashes;
|
|
489
|
-
txEffect.nullifiers = processedTx.txEffect.nullifiers;
|
|
490
|
-
txEffect.privateLogs = processedTx.txEffect.privateLogs;
|
|
491
|
-
txEffect.publicLogs = processedTx.txEffect.publicLogs;
|
|
492
|
-
txEffect.publicDataWrites = processedTx.txEffect.publicDataWrites;
|
|
493
|
-
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
494
|
-
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
495
|
-
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
496
|
-
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [
|
|
497
|
-
txEffect
|
|
498
|
-
]);
|
|
499
|
-
await this.stateMachine.handleL2Block(l2Block);
|
|
500
|
-
await forkedWorldTrees.close();
|
|
501
|
-
return returnValues ?? [];
|
|
502
667
|
}
|
|
503
|
-
async executeUtilityFunction(targetContractAddress, functionSelector, args, jobId, authorizedUtilityCallTargets) {
|
|
504
|
-
const
|
|
668
|
+
async executeUtilityFunction(from, targetContractAddress, functionSelector, args, jobId, authorizedUtilityCallTargets) {
|
|
669
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
670
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
|
|
671
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
505
672
|
if (!artifact) {
|
|
506
673
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
507
674
|
}
|
|
508
675
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
509
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
510
676
|
await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, async (call, execScopes)=>{
|
|
511
|
-
await this.executeUtilityCall(call,
|
|
677
|
+
await this.executeUtilityCall(call, {
|
|
678
|
+
scopes: execScopes,
|
|
679
|
+
jobId
|
|
680
|
+
});
|
|
512
681
|
}, blockHeader, jobId, await this.keyStore.getAccounts());
|
|
513
682
|
const call = FunctionCall.from({
|
|
514
683
|
name: artifact.name,
|
|
@@ -517,13 +686,22 @@ export class TXEOracleTopLevelContext {
|
|
|
517
686
|
type: FunctionType.UTILITY,
|
|
518
687
|
hideMsgSender: false,
|
|
519
688
|
isStatic: false,
|
|
520
|
-
args
|
|
521
|
-
|
|
689
|
+
args
|
|
690
|
+
});
|
|
691
|
+
return this.executeUtilityCall(call, {
|
|
692
|
+
from,
|
|
693
|
+
scopes: await this.keyStore.getAccounts(),
|
|
694
|
+
jobId,
|
|
695
|
+
authorizedUtilityCallTargets
|
|
522
696
|
});
|
|
523
|
-
return this.executeUtilityCall(call, await this.keyStore.getAccounts(), jobId, authorizedUtilityCallTargets);
|
|
524
697
|
}
|
|
525
|
-
async executeUtilityCall(call, scopes, jobId, authorizedUtilityCallTargets = []) {
|
|
526
|
-
const
|
|
698
|
+
async executeUtilityCall(call, { from = AztecAddress.NULL_MSG_SENDER, scopes, jobId, authorizedUtilityCallTargets = [] }) {
|
|
699
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
700
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
|
|
701
|
+
const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
702
|
+
if (!entryPointArtifact) {
|
|
703
|
+
throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
|
|
704
|
+
}
|
|
527
705
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
528
706
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
529
707
|
}
|
|
@@ -532,26 +710,34 @@ export class TXEOracleTopLevelContext {
|
|
|
532
710
|
selector: call.selector
|
|
533
711
|
});
|
|
534
712
|
try {
|
|
535
|
-
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
536
713
|
const simulator = new WASMSimulator();
|
|
537
714
|
const utilityExecutor = async (syncCall, execScopes)=>{
|
|
538
|
-
await this.executeUtilityCall(syncCall,
|
|
715
|
+
await this.executeUtilityCall(syncCall, {
|
|
716
|
+
scopes: execScopes,
|
|
717
|
+
jobId
|
|
718
|
+
});
|
|
539
719
|
};
|
|
540
720
|
const oracle = new UtilityExecutionOracle({
|
|
541
|
-
|
|
721
|
+
callContext: CallContext.from({
|
|
722
|
+
msgSender: from,
|
|
723
|
+
contractAddress: call.to,
|
|
724
|
+
functionSelector: call.selector,
|
|
725
|
+
isStaticCall: true
|
|
726
|
+
}),
|
|
542
727
|
authWitnesses: [],
|
|
543
728
|
capsules: [],
|
|
544
729
|
anchorBlockHeader,
|
|
545
|
-
|
|
730
|
+
anchoredContractData,
|
|
546
731
|
noteStore: this.noteStore,
|
|
547
732
|
keyStore: this.keyStore,
|
|
548
733
|
addressStore: this.addressStore,
|
|
549
734
|
aztecNode: this.stateMachine.node,
|
|
550
735
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
551
|
-
|
|
736
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
552
737
|
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
738
|
+
factService: new FactService(this.factStore, scopes),
|
|
553
739
|
privateEventStore: this.privateEventStore,
|
|
554
|
-
|
|
740
|
+
txResolver: this.stateMachine.txResolver,
|
|
555
741
|
contractSyncService: this.stateMachine.contractSyncService,
|
|
556
742
|
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
557
743
|
jobId,
|
|
@@ -560,9 +746,11 @@ export class TXEOracleTopLevelContext {
|
|
|
560
746
|
hooks: composeHooks({
|
|
561
747
|
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets)
|
|
562
748
|
}),
|
|
563
|
-
utilityExecutor
|
|
749
|
+
utilityExecutor,
|
|
750
|
+
// Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
|
|
751
|
+
transientArrayService: new TransientArrayService()
|
|
564
752
|
});
|
|
565
|
-
const acirExecutionResult = await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact,
|
|
753
|
+
const acirExecutionResult = await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle)).catch((err)=>{
|
|
566
754
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
567
755
|
throw new ExecutionError(err.message, {
|
|
568
756
|
contractAddress: call.to,
|
|
@@ -579,16 +767,21 @@ export class TXEOracleTopLevelContext {
|
|
|
579
767
|
}
|
|
580
768
|
close() {
|
|
581
769
|
this.logger.debug('Exiting Top Level Context');
|
|
582
|
-
return
|
|
583
|
-
this.nextBlockTimestamp,
|
|
584
|
-
this.authwits
|
|
585
|
-
|
|
770
|
+
return {
|
|
771
|
+
nextBlockTimestamp: this.nextBlockTimestamp,
|
|
772
|
+
authwits: this.authwits,
|
|
773
|
+
taggingSecretStrategies: this.taggingSecretStrategies,
|
|
774
|
+
authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets
|
|
775
|
+
};
|
|
586
776
|
}
|
|
587
777
|
async getLastBlockNumber() {
|
|
588
778
|
const block = await this.stateMachine.node.getBlock('latest');
|
|
589
779
|
return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
590
780
|
}
|
|
591
781
|
buildAuthorizeUtilityCallHook(callerContext, authorizedTargets) {
|
|
782
|
+
if (this.authorizeAllUtilityCallTargets) {
|
|
783
|
+
return authorizeAllUtilityCallsHook;
|
|
784
|
+
}
|
|
592
785
|
if (authorizedTargets.length === 0) {
|
|
593
786
|
return undefined;
|
|
594
787
|
}
|
|
@@ -597,3 +790,10 @@ export class TXEOracleTopLevelContext {
|
|
|
597
790
|
});
|
|
598
791
|
}
|
|
599
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
|
+
});
|