@aztec/txe 0.0.1-commit.f504929 → 0.0.1-commit.f5a9928
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-56AMRLSQ.js +3 -0
- package/dest/AuthRegistry-56AMRLSQ.js.map +7 -0
- package/dest/ContractClassRegistry-CRN27URB.js +3 -0
- package/dest/ContractClassRegistry-CRN27URB.js.map +7 -0
- package/dest/ContractInstanceRegistry-GRGL26IC.js +3 -0
- package/dest/ContractInstanceRegistry-GRGL26IC.js.map +7 -0
- package/dest/FeeJuice-J23RVHLW.js +3 -0
- package/dest/FeeJuice-J23RVHLW.js.map +7 -0
- package/dest/HandshakeRegistry-5.0.1-PEFCLEGP.js +3 -0
- package/dest/HandshakeRegistry-5.0.1-PEFCLEGP.js.map +7 -0
- package/dest/HandshakeRegistry-GNFACTEE.js +3 -0
- package/dest/HandshakeRegistry-GNFACTEE.js.map +7 -0
- package/dest/MultiCallEntrypoint-MIDICLQB.js +3 -0
- package/dest/MultiCallEntrypoint-MIDICLQB.js.map +7 -0
- package/dest/SchnorrAccount-ZRENHSMV.js +3 -0
- package/dest/SchnorrAccount-ZRENHSMV.js.map +7 -0
- package/dest/SchnorrInitializerlessAccount-L56LOFSV.js +3 -0
- package/dest/SchnorrInitializerlessAccount-L56LOFSV.js.map +7 -0
- package/dest/bin/check_txe_oracle_version.d.ts +2 -0
- package/dest/bin/check_txe_oracle_version.d.ts.map +1 -0
- package/dest/bin/check_txe_oracle_version.js +53 -0
- package/dest/bin/index.js +3 -30
- package/dest/bin/index.js.map +7 -0
- 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-BJVAAXNA.js +3 -0
- package/dest/chunk-BJVAAXNA.js.map +7 -0
- package/dest/chunk-C2WBKKGS.js +266 -0
- package/dest/chunk-C2WBKKGS.js.map +7 -0
- package/dest/chunk-OFS2CI6U.js +304 -0
- package/dest/chunk-OFS2CI6U.js.map +7 -0
- package/dest/constants.d.ts +5 -1
- package/dest/constants.d.ts.map +1 -1
- package/dest/constants.js +9 -1
- package/dest/dispatcher_pool.d.ts +67 -0
- package/dest/dispatcher_pool.d.ts.map +1 -0
- package/dest/dispatcher_pool.js +286 -0
- package/dest/index.d.ts +51 -7
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +72 -190
- package/dest/metafile.json +40416 -0
- package/dest/msgpackr_fr_extension.d.ts +2 -0
- package/dest/msgpackr_fr_extension.d.ts.map +1 -0
- package/dest/msgpackr_fr_extension.js +21 -0
- package/dest/oracle/interfaces.d.ts +47 -9
- 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 +26 -2
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +49 -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 +58 -17
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +259 -88
- package/dest/oracle/txe_oracle_version.d.ts +17 -0
- package/dest/oracle/txe_oracle_version.d.ts.map +1 -0
- package/dest/oracle/txe_oracle_version.js +14 -0
- package/dest/oracle/txe_private_execution_oracle.d.ts +17 -0
- package/dest/oracle/txe_private_execution_oracle.d.ts.map +1 -0
- package/dest/oracle/txe_private_execution_oracle.js +15 -0
- package/dest/rpc_server.d.ts +14 -0
- package/dest/rpc_server.d.ts.map +1 -0
- package/dest/rpc_server.js +78 -0
- package/dest/rpc_translator.d.ts +115 -228
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +791 -607
- package/dest/server.bundle.js +3 -0
- package/dest/server.bundle.js.map +7 -0
- package/dest/state_machine/archiver.d.ts +6 -5
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +28 -20
- package/dest/state_machine/dummy_p2p_client.d.ts +18 -8
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +31 -4
- package/dest/state_machine/global_variable_builder.d.ts +10 -6
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +8 -5
- package/dest/state_machine/index.d.ts +11 -5
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +50 -10
- package/dest/state_machine/mock_epoch_cache.d.ts +16 -3
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +29 -2
- package/dest/state_machine/synchronizer.d.ts +9 -6
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +10 -6
- package/dest/txe_session.d.ts +90 -19
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +315 -61
- 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 +192 -0
- package/dest/utils/encoding.d.ts.map +1 -0
- package/dest/{util → utils}/encoding.js +7 -2
- package/dest/{util → utils}/expected_failure_error.d.ts +1 -1
- package/dest/utils/expected_failure_error.d.ts.map +1 -0
- 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/{util → utils}/txe_account_store.d.ts +1 -1
- package/dest/utils/txe_account_store.d.ts.map +1 -0
- 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 +20 -0
- package/dest/utils/txe_public_contract_data_source.d.ts.map +1 -0
- package/dest/{util → utils}/txe_public_contract_data_source.js +8 -7
- package/dest/worker.bundle.js +3 -0
- package/dest/worker.bundle.js.map +7 -0
- package/dest/worker.d.ts +2 -0
- package/dest/worker.d.ts.map +1 -0
- package/dest/worker.js +92 -0
- package/package.json +38 -21
- package/src/bin/check_txe_oracle_version.ts +67 -0
- package/src/bin/index.ts +11 -2
- package/src/bin/oracle_test_server.ts +51 -0
- package/src/constants.ts +11 -1
- package/src/dispatcher_pool.ts +317 -0
- package/src/index.ts +99 -227
- package/src/msgpackr_fr_extension.ts +23 -0
- package/src/oracle/interfaces.ts +47 -8
- 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 +62 -0
- package/src/oracle/txe_oracle_registry.ts +556 -0
- package/src/oracle/txe_oracle_top_level_context.ts +342 -97
- package/src/oracle/txe_oracle_version.ts +17 -0
- package/src/oracle/txe_private_execution_oracle.ts +30 -0
- package/src/rpc_server.ts +87 -0
- package/src/rpc_translator.ts +882 -870
- package/src/state_machine/archiver.ts +41 -20
- package/src/state_machine/dummy_p2p_client.ts +49 -12
- package/src/state_machine/global_variable_builder.ts +12 -11
- package/src/state_machine/index.ts +63 -28
- package/src/state_machine/mock_epoch_cache.ts +38 -3
- package/src/state_machine/synchronizer.ts +13 -7
- package/src/txe_session.ts +552 -75
- package/src/utils/block_creation.ts +2 -1
- package/src/{util → utils}/encoding.ts +8 -2
- package/src/utils/tx_effect_creation.ts +0 -2
- package/src/utils/txe_artifact_resolver.ts +217 -0
- package/src/{util → utils}/txe_public_contract_data_source.ts +6 -6
- package/src/worker.ts +98 -0
- package/dest/util/encoding.d.ts +0 -720
- package/dest/util/encoding.d.ts.map +0 -1
- package/dest/util/expected_failure_error.d.ts.map +0 -1
- package/dest/util/txe_account_store.d.ts.map +0 -1
- package/dest/util/txe_public_contract_data_source.d.ts +0 -20
- package/dest/util/txe_public_contract_data_source.d.ts.map +0 -1
- /package/dest/{util → utils}/expected_failure_error.js +0 -0
- /package/dest/{util → utils}/txe_account_store.js +0 -0
- /package/src/{util → utils}/expected_failure_error.ts +0 -0
- /package/src/{util → utils}/txe_account_store.ts +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS,
|
|
1
|
+
import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, MAX_PRIVATE_LOGS_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
|
|
2
2
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import { Schnorr } from '@aztec/foundation/crypto/schnorr';
|
|
4
4
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
5
|
import { LogLevels, applyStringFormatting, createLogger } from '@aztec/foundation/log';
|
|
6
6
|
import { TestDateProvider } from '@aztec/foundation/timer';
|
|
7
|
-
import {
|
|
8
|
-
import { ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache,
|
|
7
|
+
import { AnchoredContractData, CapsuleService, FactService, ORACLE_VERSION_MAJOR, composeHooks, enrichPublicSimulationError } from '@aztec/pxe/server';
|
|
8
|
+
import { CONTRACT_INSTANCE, ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache, PrivateExecutionOracle, TransientArrayService, UtilityExecutionOracle, buildACIRCallback, executePrivateFunction, generateSimulatedProvingResult } from '@aztec/pxe/simulator';
|
|
9
9
|
import { ExecutionError, WASMSimulator, createSimulationError, extractCallStack, resolveAssertionMessageFromError, toACVMWitness, witnessMapToFields } from '@aztec/simulator/client';
|
|
10
10
|
import { CppPublicTxSimulator, GuardedMerkleTreeOperations, PublicContractsDB, PublicProcessor } from '@aztec/simulator/server';
|
|
11
11
|
import { FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
@@ -13,17 +13,21 @@ import { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
|
13
13
|
import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
14
14
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
15
15
|
import { computePartialAddress } from '@aztec/stdlib/contract';
|
|
16
|
-
import { Gas, GasFees
|
|
16
|
+
import { Gas, GasFees } from '@aztec/stdlib/gas';
|
|
17
17
|
import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
|
|
18
18
|
import { PartialPrivateTailPublicInputsForPublic, PrivateKernelTailCircuitPublicInputs, PrivateToPublicAccumulatedData, PublicCallRequest } from '@aztec/stdlib/kernel';
|
|
19
|
+
import { deriveKeys, hashPublicKey } from '@aztec/stdlib/keys';
|
|
20
|
+
import { AppTaggingSecretKind } from '@aztec/stdlib/logs';
|
|
21
|
+
import { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
|
|
19
22
|
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
20
23
|
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
21
24
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
22
25
|
import { CallContext, HashedValues, PrivateExecutionResult, Tx, TxConstantData, TxContext, TxEffect, TxHash, collectNested } from '@aztec/stdlib/tx';
|
|
23
|
-
import { ForkCheckpoint } from '@aztec/world-state';
|
|
24
|
-
import { DEFAULT_ADDRESS } from '../constants.js';
|
|
25
|
-
import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
|
|
26
|
+
import { ForkCheckpoint } from '@aztec/world-state/native';
|
|
27
|
+
import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
|
|
26
28
|
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
29
|
+
import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
|
|
30
|
+
import { makeResolveTaggingSecretStrategyHook } from './tagging_secret_strategy.js';
|
|
27
31
|
export class TXEOracleTopLevelContext {
|
|
28
32
|
stateMachine;
|
|
29
33
|
contractStore;
|
|
@@ -33,17 +37,23 @@ export class TXEOracleTopLevelContext {
|
|
|
33
37
|
accountStore;
|
|
34
38
|
senderTaggingStore;
|
|
35
39
|
recipientTaggingStore;
|
|
36
|
-
|
|
40
|
+
taggingSecretSourcesStore;
|
|
37
41
|
capsuleStore;
|
|
42
|
+
factStore;
|
|
38
43
|
privateEventStore;
|
|
39
44
|
nextBlockTimestamp;
|
|
40
45
|
version;
|
|
41
46
|
chainId;
|
|
42
47
|
authwits;
|
|
48
|
+
taggingSecretStrategies;
|
|
49
|
+
authorizeAllUtilityCallTargets;
|
|
50
|
+
artifactResolver;
|
|
51
|
+
rootPath;
|
|
52
|
+
packageName;
|
|
43
53
|
isMisc;
|
|
44
54
|
isTxe;
|
|
45
55
|
logger;
|
|
46
|
-
constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore,
|
|
56
|
+
constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, taggingSecretSourcesStore, capsuleStore, factStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits, taggingSecretStrategies, authorizeAllUtilityCallTargets, artifactResolver, rootPath, packageName){
|
|
47
57
|
this.stateMachine = stateMachine;
|
|
48
58
|
this.contractStore = contractStore;
|
|
49
59
|
this.noteStore = noteStore;
|
|
@@ -52,22 +62,38 @@ export class TXEOracleTopLevelContext {
|
|
|
52
62
|
this.accountStore = accountStore;
|
|
53
63
|
this.senderTaggingStore = senderTaggingStore;
|
|
54
64
|
this.recipientTaggingStore = recipientTaggingStore;
|
|
55
|
-
this.
|
|
65
|
+
this.taggingSecretSourcesStore = taggingSecretSourcesStore;
|
|
56
66
|
this.capsuleStore = capsuleStore;
|
|
67
|
+
this.factStore = factStore;
|
|
57
68
|
this.privateEventStore = privateEventStore;
|
|
58
69
|
this.nextBlockTimestamp = nextBlockTimestamp;
|
|
59
70
|
this.version = version;
|
|
60
71
|
this.chainId = chainId;
|
|
61
72
|
this.authwits = authwits;
|
|
73
|
+
this.taggingSecretStrategies = taggingSecretStrategies;
|
|
74
|
+
this.authorizeAllUtilityCallTargets = authorizeAllUtilityCallTargets;
|
|
75
|
+
this.artifactResolver = artifactResolver;
|
|
76
|
+
this.rootPath = rootPath;
|
|
77
|
+
this.packageName = packageName;
|
|
62
78
|
this.isMisc = true;
|
|
63
79
|
this.isTxe = true;
|
|
64
80
|
this.logger = createLogger('txe:top_level_context');
|
|
65
81
|
this.logger.debug('Entering Top Level Context');
|
|
66
82
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
83
|
+
contractOracleVersion;
|
|
84
|
+
assertCompatibleOracleVersion(major, minor) {
|
|
85
|
+
if (major !== ORACLE_VERSION_MAJOR) {
|
|
86
|
+
const hint = major > ORACLE_VERSION_MAJOR ? 'The contract was compiled with a newer version of Aztec.nr than this aztec cli version supports. Upgrade your aztec cli version to a compatible version.' : 'The contract was compiled with an older version of Aztec.nr than this aztec cli version supports. Recompile the contract with a compatible version of Aztec.nr.';
|
|
87
|
+
throw new Error(`Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`);
|
|
70
88
|
}
|
|
89
|
+
this.contractOracleVersion = {
|
|
90
|
+
major,
|
|
91
|
+
minor
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
// Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
|
|
95
|
+
nonOracleFunctionGetContractOracleVersion() {
|
|
96
|
+
return this.contractOracleVersion;
|
|
71
97
|
}
|
|
72
98
|
// This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
|
|
73
99
|
// setup.
|
|
@@ -75,7 +101,7 @@ export class TXEOracleTopLevelContext {
|
|
|
75
101
|
return Fr.random();
|
|
76
102
|
}
|
|
77
103
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
78
|
-
log(level, message, fields) {
|
|
104
|
+
log(level, message, _fieldsSize, fields) {
|
|
79
105
|
if (!LogLevels[level]) {
|
|
80
106
|
throw new Error(`Invalid log level: ${level}`);
|
|
81
107
|
}
|
|
@@ -95,20 +121,27 @@ export class TXEOracleTopLevelContext {
|
|
|
95
121
|
return Promise.resolve(this.nextBlockTimestamp);
|
|
96
122
|
}
|
|
97
123
|
async getLastBlockTimestamp() {
|
|
98
|
-
return (await this.stateMachine.node.
|
|
124
|
+
return (await this.stateMachine.node.getBlockData('latest')).header.globalVariables.timestamp;
|
|
99
125
|
}
|
|
100
126
|
async getLastTxEffects() {
|
|
101
127
|
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
102
|
-
const block = await this.stateMachine.archiver.getBlock(
|
|
128
|
+
const block = await this.stateMachine.archiver.getBlock({
|
|
129
|
+
number: latestBlockNumber
|
|
130
|
+
});
|
|
103
131
|
if (block.body.txEffects.length != 1) {
|
|
104
132
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
105
133
|
throw new Error(`Expected a single transaction in the last block, found ${block.body.txEffects.length}`);
|
|
106
134
|
}
|
|
107
135
|
const txEffects = block.body.txEffects[0];
|
|
136
|
+
const privateLogs = txEffects.privateLogs;
|
|
137
|
+
if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
|
|
138
|
+
throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
|
|
139
|
+
}
|
|
108
140
|
return {
|
|
109
141
|
txHash: txEffects.txHash,
|
|
110
142
|
noteHashes: txEffects.noteHashes,
|
|
111
|
-
nullifiers: txEffects.nullifiers
|
|
143
|
+
nullifiers: txEffects.nullifiers,
|
|
144
|
+
privateLogs
|
|
112
145
|
};
|
|
113
146
|
}
|
|
114
147
|
async syncContractNonOracleMethod(contractAddress, scope, jobId) {
|
|
@@ -118,13 +151,16 @@ export class TXEOracleTopLevelContext {
|
|
|
118
151
|
}
|
|
119
152
|
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
120
153
|
await this.stateMachine.contractSyncService.ensureContractSynced(contractAddress, null, async (call, execScopes)=>{
|
|
121
|
-
await this.executeUtilityCall(call,
|
|
154
|
+
await this.executeUtilityCall(call, {
|
|
155
|
+
scopes: execScopes,
|
|
156
|
+
jobId
|
|
157
|
+
});
|
|
122
158
|
}, blockHeader, jobId, [
|
|
123
159
|
scope
|
|
124
160
|
]);
|
|
125
161
|
}
|
|
126
162
|
async getPrivateEvents(selector, contractAddress, scope) {
|
|
127
|
-
|
|
163
|
+
const events = (await this.privateEventStore.getPrivateEvents(selector, {
|
|
128
164
|
contractAddress,
|
|
129
165
|
scopes: [
|
|
130
166
|
scope
|
|
@@ -132,6 +168,13 @@ export class TXEOracleTopLevelContext {
|
|
|
132
168
|
fromBlock: 0,
|
|
133
169
|
toBlock: await this.getLastBlockNumber() + 1
|
|
134
170
|
})).map((e)=>e.packedEvent);
|
|
171
|
+
if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
|
|
172
|
+
throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
|
|
173
|
+
}
|
|
174
|
+
if (events.some((e)=>e.length > MAX_PRIVATE_EVENT_LEN)) {
|
|
175
|
+
throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
|
|
176
|
+
}
|
|
177
|
+
return events;
|
|
135
178
|
}
|
|
136
179
|
async advanceBlocksBy(blocks) {
|
|
137
180
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
@@ -143,35 +186,59 @@ export class TXEOracleTopLevelContext {
|
|
|
143
186
|
this.logger.debug(`time traveling ${duration} seconds`);
|
|
144
187
|
this.nextBlockTimestamp += duration;
|
|
145
188
|
}
|
|
146
|
-
|
|
189
|
+
deploymentNullifier(address) {
|
|
190
|
+
return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
|
|
191
|
+
}
|
|
192
|
+
async deploy(contractPath, initializer, args, secret, salt, deployer) {
|
|
193
|
+
const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
|
|
194
|
+
rootPath: this.rootPath,
|
|
195
|
+
packageName: this.packageName,
|
|
196
|
+
contractPath,
|
|
197
|
+
initializer,
|
|
198
|
+
args,
|
|
199
|
+
secret,
|
|
200
|
+
salt,
|
|
201
|
+
deployer
|
|
202
|
+
});
|
|
147
203
|
// Emit deployment nullifier
|
|
148
204
|
await this.mineBlock({
|
|
149
205
|
nullifiers: [
|
|
150
|
-
await
|
|
206
|
+
await this.deploymentNullifier(instance.address)
|
|
151
207
|
]
|
|
152
208
|
});
|
|
153
209
|
if (!secret.equals(Fr.ZERO)) {
|
|
154
|
-
await this.
|
|
210
|
+
await this.registerContractAndAddAccount(artifact, instance, secret);
|
|
155
211
|
} else {
|
|
156
212
|
await this.contractStore.addContractInstance(instance);
|
|
157
213
|
await this.contractStore.addContractArtifact(artifact);
|
|
158
214
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
159
215
|
}
|
|
216
|
+
return CONTRACT_INSTANCE.serialization.fn(instance).flat();
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
|
|
220
|
+
*/ async mineDeploymentNullifiers(addresses) {
|
|
221
|
+
await this.mineBlock({
|
|
222
|
+
nullifiers: await Promise.all(addresses.map((address)=>this.deploymentNullifier(address)))
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
async addAccount(secret) {
|
|
226
|
+
const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
|
|
227
|
+
return this.registerContractAndAddAccount(artifact, instance, secret);
|
|
160
228
|
}
|
|
161
|
-
async
|
|
229
|
+
async registerContractAndAddAccount(artifact, instance, secret) {
|
|
162
230
|
const partialAddress = await computePartialAddress(instance);
|
|
163
231
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
164
232
|
await this.contractStore.addContractInstance(instance);
|
|
165
233
|
await this.contractStore.addContractArtifact(artifact);
|
|
166
|
-
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
234
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
167
235
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
168
236
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
169
237
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
170
238
|
return completeAddress;
|
|
171
239
|
}
|
|
172
|
-
async createAccount(secret) {
|
|
173
|
-
|
|
174
|
-
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
240
|
+
async createAccount(secret, partialAddress) {
|
|
241
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
175
242
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
176
243
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
177
244
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -179,14 +246,39 @@ export class TXEOracleTopLevelContext {
|
|
|
179
246
|
}
|
|
180
247
|
async addAuthWitness(address, messageHash) {
|
|
181
248
|
const account = await this.accountStore.getAccount(address);
|
|
182
|
-
const
|
|
249
|
+
const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
|
|
250
|
+
const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
|
|
183
251
|
const schnorr = new Schnorr();
|
|
184
|
-
const signature = await schnorr.constructSignature(messageHash
|
|
185
|
-
const authWitness = new AuthWitness(messageHash,
|
|
186
|
-
...signature.toBuffer()
|
|
187
|
-
]);
|
|
252
|
+
const signature = await schnorr.constructSignature(messageHash, privateKey);
|
|
253
|
+
const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
|
|
188
254
|
this.authwits.set(authWitness.requestHash.toString(), authWitness);
|
|
189
255
|
}
|
|
256
|
+
setTaggingSecretStrategies(unconstrainedStrategy, constrainedStrategy) {
|
|
257
|
+
const apply = (mode, strategy)=>{
|
|
258
|
+
if (strategy.isSome()) {
|
|
259
|
+
this.taggingSecretStrategies.set(mode, strategy.value);
|
|
260
|
+
} else {
|
|
261
|
+
this.taggingSecretStrategies.delete(mode);
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
apply(AppTaggingSecretKind.UNCONSTRAINED, unconstrainedStrategy);
|
|
265
|
+
apply(AppTaggingSecretKind.CONSTRAINED, constrainedStrategy);
|
|
266
|
+
}
|
|
267
|
+
setAuthorizeAllUtilityCallTargets(authorizeAll) {
|
|
268
|
+
this.authorizeAllUtilityCallTargets = authorizeAll;
|
|
269
|
+
}
|
|
270
|
+
async sendL1ToL2Message(content, secretHash, sender, recipient) {
|
|
271
|
+
// Messages are appended to the tree, so the next free slot is simply the current tree size.
|
|
272
|
+
const { size } = await this.stateMachine.synchronizer.getCommitted().getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
|
|
273
|
+
const leafIndex = new Fr(size);
|
|
274
|
+
const message = new L1ToL2Message(new L1Actor(sender, this.chainId.toNumber()), new L2Actor(recipient, this.version.toNumber()), content, secretHash, leafIndex);
|
|
275
|
+
await this.mineBlock({
|
|
276
|
+
l1ToL2Messages: [
|
|
277
|
+
message.hash()
|
|
278
|
+
]
|
|
279
|
+
});
|
|
280
|
+
return leafIndex;
|
|
281
|
+
}
|
|
190
282
|
async mineBlock(options = {}) {
|
|
191
283
|
const blockNumber = await this.getNextBlockNumber();
|
|
192
284
|
const txEffect = TxEffect.empty();
|
|
@@ -196,7 +288,7 @@ export class TXEOracleTopLevelContext {
|
|
|
196
288
|
];
|
|
197
289
|
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
198
290
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
199
|
-
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
291
|
+
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
|
|
200
292
|
const globals = makeGlobalVariables(undefined, {
|
|
201
293
|
blockNumber,
|
|
202
294
|
timestamp: this.nextBlockTimestamp,
|
|
@@ -208,31 +300,32 @@ export class TXEOracleTopLevelContext {
|
|
|
208
300
|
]);
|
|
209
301
|
await forkedWorldTrees.close();
|
|
210
302
|
this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
|
|
211
|
-
await this.stateMachine.handleL2Block(block);
|
|
303
|
+
await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
|
|
212
304
|
}
|
|
213
|
-
async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, jobId) {
|
|
214
|
-
|
|
215
|
-
const
|
|
305
|
+
async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, additionalScopes = [], jobId, authorizedUtilityCallTargets, gasSettings) {
|
|
306
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
307
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
|
|
308
|
+
this.logger.verbose(`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
|
|
309
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
216
310
|
if (!artifact) {
|
|
217
311
|
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';
|
|
218
312
|
throw new Error(message);
|
|
219
313
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
from
|
|
314
|
+
const scopes = from === undefined ? additionalScopes : [
|
|
315
|
+
from,
|
|
316
|
+
...additionalScopes
|
|
224
317
|
];
|
|
225
318
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
226
319
|
const utilityExecutor = async (call, execScopes)=>{
|
|
227
|
-
await this.executeUtilityCall(call,
|
|
320
|
+
await this.executeUtilityCall(call, {
|
|
321
|
+
scopes: execScopes,
|
|
322
|
+
jobId
|
|
323
|
+
});
|
|
228
324
|
};
|
|
229
|
-
|
|
230
|
-
await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, effectiveScopes);
|
|
325
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, scopes);
|
|
231
326
|
const blockNumber = await this.getNextBlockNumber();
|
|
232
|
-
const
|
|
233
|
-
const
|
|
234
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
235
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
327
|
+
const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
|
|
328
|
+
const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
|
|
236
329
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
237
330
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
238
331
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
@@ -243,9 +336,12 @@ export class TXEOracleTopLevelContext {
|
|
|
243
336
|
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
244
337
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
245
338
|
const simulator = new WASMSimulator();
|
|
339
|
+
const transientArrayService = new TransientArrayService();
|
|
246
340
|
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
247
341
|
argsHash,
|
|
248
342
|
txContext,
|
|
343
|
+
// The TXE does not run the init kernel's salt binding, so no tx-request salt is in scope.
|
|
344
|
+
txRequestSalt: Fr.ZERO,
|
|
249
345
|
callContext,
|
|
250
346
|
anchorBlockHeader: blockHeader,
|
|
251
347
|
utilityExecutor,
|
|
@@ -256,25 +352,33 @@ export class TXEOracleTopLevelContext {
|
|
|
256
352
|
]),
|
|
257
353
|
noteCache,
|
|
258
354
|
taggingIndexCache,
|
|
259
|
-
|
|
355
|
+
anchoredContractData,
|
|
260
356
|
noteStore: this.noteStore,
|
|
261
357
|
keyStore: this.keyStore,
|
|
262
358
|
addressStore: this.addressStore,
|
|
263
359
|
aztecNode: this.stateMachine.node,
|
|
264
360
|
senderTaggingStore: this.senderTaggingStore,
|
|
265
361
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
266
|
-
|
|
267
|
-
|
|
362
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
363
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
364
|
+
factService: new FactService(this.factStore, scopes),
|
|
268
365
|
privateEventStore: this.privateEventStore,
|
|
269
366
|
contractSyncService: this.stateMachine.contractSyncService,
|
|
270
367
|
jobId,
|
|
271
368
|
totalPublicCalldataCount: 0,
|
|
272
369
|
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
273
|
-
scopes
|
|
370
|
+
scopes,
|
|
274
371
|
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
275
372
|
// contract would perform, including setting senderForTags.
|
|
276
373
|
senderForTags: from,
|
|
277
|
-
simulator
|
|
374
|
+
simulator,
|
|
375
|
+
txResolver: this.stateMachine.txResolver,
|
|
376
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
377
|
+
hooks: composeHooks({
|
|
378
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(isStaticCall ? 'private view' : 'private', authorizedUtilityCallTargets),
|
|
379
|
+
resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies)
|
|
380
|
+
}),
|
|
381
|
+
transientArrayService
|
|
278
382
|
});
|
|
279
383
|
// 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.
|
|
280
384
|
let result;
|
|
@@ -287,10 +391,9 @@ export class TXEOracleTopLevelContext {
|
|
|
287
391
|
r.publicInputs.publicTeardownCallRequest
|
|
288
392
|
]));
|
|
289
393
|
const publicFunctionsCalldata = await Promise.all(publicCallRequests.map(async (r)=>{
|
|
290
|
-
const calldata = await privateExecutionOracle.
|
|
394
|
+
const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
|
|
291
395
|
return new HashedValues(calldata, r.calldataHash);
|
|
292
396
|
}));
|
|
293
|
-
noteCache.finish();
|
|
294
397
|
const nonceGenerator = noteCache.getNonceGenerator();
|
|
295
398
|
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
296
399
|
} catch (err) {
|
|
@@ -299,7 +402,7 @@ export class TXEOracleTopLevelContext {
|
|
|
299
402
|
// According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
|
|
300
403
|
// the nonce generator for the note hashes.
|
|
301
404
|
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
302
|
-
const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>
|
|
405
|
+
const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>anchoredContractData.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
|
|
303
406
|
const globals = makeGlobalVariables();
|
|
304
407
|
globals.blockNumber = blockNumber;
|
|
305
408
|
globals.timestamp = this.nextBlockTimestamp;
|
|
@@ -338,7 +441,7 @@ export class TXEOracleTopLevelContext {
|
|
|
338
441
|
} else if (!processedTx.revertCode.isOK()) {
|
|
339
442
|
if (processedTx.revertReason) {
|
|
340
443
|
try {
|
|
341
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
444
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, await this.stateMachine.anchorBlockStore.getBlockHeader(), this.logger);
|
|
342
445
|
// eslint-disable-next-line no-empty
|
|
343
446
|
} catch {}
|
|
344
447
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -346,10 +449,20 @@ export class TXEOracleTopLevelContext {
|
|
|
346
449
|
throw new Error('Contract execution has reverted');
|
|
347
450
|
}
|
|
348
451
|
}
|
|
452
|
+
// Walk the nested private-call tree and collect every offchain effect the transaction emitted.
|
|
453
|
+
// PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
|
|
454
|
+
// `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
|
|
455
|
+
// we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
|
|
456
|
+
const offchainEffects = collectNested([
|
|
457
|
+
executionResult
|
|
458
|
+
], (r)=>r.offchainEffects.map((e)=>e.data));
|
|
349
459
|
if (isStaticCall) {
|
|
350
460
|
await checkpoint.revert();
|
|
351
461
|
await forkedWorldTrees.close();
|
|
352
|
-
return
|
|
462
|
+
return {
|
|
463
|
+
returnValues: executionResult.returnValues ?? [],
|
|
464
|
+
offchainEffects
|
|
465
|
+
};
|
|
353
466
|
}
|
|
354
467
|
const txEffect = TxEffect.empty();
|
|
355
468
|
txEffect.noteHashes = processedTx.txEffect.noteHashes;
|
|
@@ -365,16 +478,17 @@ export class TXEOracleTopLevelContext {
|
|
|
365
478
|
]);
|
|
366
479
|
await this.stateMachine.handleL2Block(l2Block);
|
|
367
480
|
await forkedWorldTrees.close();
|
|
368
|
-
return
|
|
481
|
+
return {
|
|
482
|
+
returnValues: executionResult.returnValues ?? [],
|
|
483
|
+
offchainEffects
|
|
484
|
+
};
|
|
369
485
|
}
|
|
370
|
-
async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall) {
|
|
371
|
-
|
|
486
|
+
async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall, gasSettings) {
|
|
487
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
488
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
|
|
489
|
+
this.logger.verbose(`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
|
|
372
490
|
const blockNumber = await this.getNextBlockNumber();
|
|
373
|
-
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
374
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
375
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
376
491
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
377
|
-
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
378
492
|
const calldataHash = await computeCalldataHash(calldata);
|
|
379
493
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
380
494
|
const globals = makeGlobalVariables();
|
|
@@ -405,7 +519,7 @@ export class TXEOracleTopLevelContext {
|
|
|
405
519
|
// The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
|
|
406
520
|
// may require producing reverts.
|
|
407
521
|
const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
408
|
-
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from, targetContractAddress, isStaticCall, calldataHash);
|
|
522
|
+
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from ?? AztecAddress.NULL_MSG_SENDER, targetContractAddress, isStaticCall, calldataHash);
|
|
409
523
|
const inputsForPublic = new PartialPrivateTailPublicInputsForPublic(nonRevertibleAccumulatedData, revertibleAccumulatedData, PublicCallRequest.empty());
|
|
410
524
|
const constantData = new TxConstantData(anchorBlockHeader, txContext, Fr.zero(), Fr.zero());
|
|
411
525
|
const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*expirationTimestamp=*/ 0n, inputsForPublic, undefined);
|
|
@@ -431,7 +545,7 @@ export class TXEOracleTopLevelContext {
|
|
|
431
545
|
} else if (!processedTx.revertCode.isOK()) {
|
|
432
546
|
if (processedTx.revertReason) {
|
|
433
547
|
try {
|
|
434
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
548
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader, this.logger);
|
|
435
549
|
// eslint-disable-next-line no-empty
|
|
436
550
|
} catch {}
|
|
437
551
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -461,16 +575,20 @@ export class TXEOracleTopLevelContext {
|
|
|
461
575
|
await forkedWorldTrees.close();
|
|
462
576
|
return returnValues ?? [];
|
|
463
577
|
}
|
|
464
|
-
async executeUtilityFunction(targetContractAddress, functionSelector, args, jobId) {
|
|
465
|
-
const
|
|
578
|
+
async executeUtilityFunction(from, targetContractAddress, functionSelector, args, jobId, authorizedUtilityCallTargets) {
|
|
579
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
580
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
|
|
581
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
466
582
|
if (!artifact) {
|
|
467
583
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
468
584
|
}
|
|
469
585
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
470
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
471
586
|
await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, async (call, execScopes)=>{
|
|
472
|
-
await this.executeUtilityCall(call,
|
|
473
|
-
|
|
587
|
+
await this.executeUtilityCall(call, {
|
|
588
|
+
scopes: execScopes,
|
|
589
|
+
jobId
|
|
590
|
+
});
|
|
591
|
+
}, blockHeader, jobId, await this.keyStore.getAccounts());
|
|
474
592
|
const call = FunctionCall.from({
|
|
475
593
|
name: artifact.name,
|
|
476
594
|
to: targetContractAddress,
|
|
@@ -481,10 +599,20 @@ export class TXEOracleTopLevelContext {
|
|
|
481
599
|
args,
|
|
482
600
|
returnTypes: []
|
|
483
601
|
});
|
|
484
|
-
return this.executeUtilityCall(call,
|
|
602
|
+
return this.executeUtilityCall(call, {
|
|
603
|
+
from,
|
|
604
|
+
scopes: await this.keyStore.getAccounts(),
|
|
605
|
+
jobId,
|
|
606
|
+
authorizedUtilityCallTargets
|
|
607
|
+
});
|
|
485
608
|
}
|
|
486
|
-
async executeUtilityCall(call, scopes, jobId) {
|
|
487
|
-
const
|
|
609
|
+
async executeUtilityCall(call, { from = AztecAddress.NULL_MSG_SENDER, scopes, jobId, authorizedUtilityCallTargets = [] }) {
|
|
610
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
611
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
|
|
612
|
+
const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
613
|
+
if (!entryPointArtifact) {
|
|
614
|
+
throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
|
|
615
|
+
}
|
|
488
616
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
489
617
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
490
618
|
}
|
|
@@ -493,25 +621,48 @@ export class TXEOracleTopLevelContext {
|
|
|
493
621
|
selector: call.selector
|
|
494
622
|
});
|
|
495
623
|
try {
|
|
496
|
-
const
|
|
624
|
+
const simulator = new WASMSimulator();
|
|
625
|
+
const utilityExecutor = async (syncCall, execScopes)=>{
|
|
626
|
+
await this.executeUtilityCall(syncCall, {
|
|
627
|
+
scopes: execScopes,
|
|
628
|
+
jobId,
|
|
629
|
+
authorizedUtilityCallTargets
|
|
630
|
+
});
|
|
631
|
+
};
|
|
497
632
|
const oracle = new UtilityExecutionOracle({
|
|
498
|
-
|
|
633
|
+
callContext: CallContext.from({
|
|
634
|
+
msgSender: from,
|
|
635
|
+
contractAddress: call.to,
|
|
636
|
+
functionSelector: call.selector,
|
|
637
|
+
isStaticCall: true
|
|
638
|
+
}),
|
|
499
639
|
authWitnesses: [],
|
|
500
640
|
capsules: [],
|
|
501
641
|
anchorBlockHeader,
|
|
502
|
-
|
|
642
|
+
anchoredContractData,
|
|
503
643
|
noteStore: this.noteStore,
|
|
504
644
|
keyStore: this.keyStore,
|
|
505
645
|
addressStore: this.addressStore,
|
|
506
646
|
aztecNode: this.stateMachine.node,
|
|
507
647
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
508
|
-
|
|
509
|
-
|
|
648
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
649
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
650
|
+
factService: new FactService(this.factStore, scopes),
|
|
510
651
|
privateEventStore: this.privateEventStore,
|
|
652
|
+
txResolver: this.stateMachine.txResolver,
|
|
653
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
654
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
511
655
|
jobId,
|
|
512
|
-
scopes
|
|
656
|
+
scopes,
|
|
657
|
+
simulator,
|
|
658
|
+
utilityExecutor,
|
|
659
|
+
hooks: composeHooks({
|
|
660
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets)
|
|
661
|
+
}),
|
|
662
|
+
// Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
|
|
663
|
+
transientArrayService: new TransientArrayService()
|
|
513
664
|
});
|
|
514
|
-
const acirExecutionResult = await
|
|
665
|
+
const acirExecutionResult = await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle)).catch((err)=>{
|
|
515
666
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
516
667
|
throw new ExecutionError(err.message, {
|
|
517
668
|
contractAddress: call.to,
|
|
@@ -528,13 +679,33 @@ export class TXEOracleTopLevelContext {
|
|
|
528
679
|
}
|
|
529
680
|
close() {
|
|
530
681
|
this.logger.debug('Exiting Top Level Context');
|
|
531
|
-
return
|
|
532
|
-
this.nextBlockTimestamp,
|
|
533
|
-
this.authwits
|
|
534
|
-
|
|
682
|
+
return {
|
|
683
|
+
nextBlockTimestamp: this.nextBlockTimestamp,
|
|
684
|
+
authwits: this.authwits,
|
|
685
|
+
taggingSecretStrategies: this.taggingSecretStrategies,
|
|
686
|
+
authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets
|
|
687
|
+
};
|
|
535
688
|
}
|
|
536
689
|
async getLastBlockNumber() {
|
|
537
|
-
const
|
|
538
|
-
return
|
|
690
|
+
const block = await this.stateMachine.node.getBlock('latest');
|
|
691
|
+
return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
692
|
+
}
|
|
693
|
+
buildAuthorizeUtilityCallHook(callerContext, authorizedTargets) {
|
|
694
|
+
if (this.authorizeAllUtilityCallTargets) {
|
|
695
|
+
return authorizeAllUtilityCallsHook;
|
|
696
|
+
}
|
|
697
|
+
if (authorizedTargets.length === 0) {
|
|
698
|
+
return undefined;
|
|
699
|
+
}
|
|
700
|
+
return (req)=>Promise.resolve({
|
|
701
|
+
authorized: req.callerContext === callerContext && authorizedTargets.some((t)=>t.equals(req.target))
|
|
702
|
+
});
|
|
539
703
|
}
|
|
540
704
|
}
|
|
705
|
+
/**
|
|
706
|
+
* An `authorizeUtilityCall` hook that authorizes every cross-contract utility call.
|
|
707
|
+
*
|
|
708
|
+
* Backs the `aztec_txe_setAuthorizeAllUtilityCallTargets` oracle.
|
|
709
|
+
*/ export const authorizeAllUtilityCallsHook = ()=>Promise.resolve({
|
|
710
|
+
authorized: true
|
|
711
|
+
});
|