@aztec/txe 0.0.1-commit.3fd054f6 → 0.0.1-commit.431c48d
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-LVLJKGGH.js +266 -0
- package/dest/chunk-LVLJKGGH.js.map +7 -0
- package/dest/chunk-OVMCQ5A6.js +304 -0
- package/dest/chunk-OVMCQ5A6.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 +40494 -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 -18
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +288 -98
- 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 -233
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +791 -636
- package/dest/server.bundle.js +3 -0
- package/dest/server.bundle.js.map +7 -0
- package/dest/state_machine/archiver.d.ts +4 -3
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +24 -14
- 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 -7
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +52 -14
- package/dest/state_machine/mock_epoch_cache.d.ts +1 -2
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +0 -3
- package/dest/state_machine/synchronizer.d.ts +5 -2
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +7 -3
- package/dest/txe_session.d.ts +90 -20
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +319 -73
- 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 +7 -4
- 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 +364 -121
- 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 +880 -902
- package/src/state_machine/archiver.ts +37 -16
- 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 -32
- package/src/state_machine/mock_epoch_cache.ts +0 -4
- package/src/state_machine/synchronizer.ts +9 -3
- package/src/txe_session.ts +554 -89
- 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 -4
- package/src/worker.ts +98 -0
- package/dest/util/encoding.d.ts +0 -788
- 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,18 +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;
|
|
43
|
-
|
|
48
|
+
taggingSecretStrategies;
|
|
49
|
+
authorizeAllUtilityCallTargets;
|
|
50
|
+
artifactResolver;
|
|
51
|
+
rootPath;
|
|
52
|
+
packageName;
|
|
44
53
|
isMisc;
|
|
45
54
|
isTxe;
|
|
46
55
|
logger;
|
|
47
|
-
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){
|
|
48
57
|
this.stateMachine = stateMachine;
|
|
49
58
|
this.contractStore = contractStore;
|
|
50
59
|
this.noteStore = noteStore;
|
|
@@ -53,23 +62,38 @@ export class TXEOracleTopLevelContext {
|
|
|
53
62
|
this.accountStore = accountStore;
|
|
54
63
|
this.senderTaggingStore = senderTaggingStore;
|
|
55
64
|
this.recipientTaggingStore = recipientTaggingStore;
|
|
56
|
-
this.
|
|
65
|
+
this.taggingSecretSourcesStore = taggingSecretSourcesStore;
|
|
57
66
|
this.capsuleStore = capsuleStore;
|
|
67
|
+
this.factStore = factStore;
|
|
58
68
|
this.privateEventStore = privateEventStore;
|
|
59
69
|
this.nextBlockTimestamp = nextBlockTimestamp;
|
|
60
70
|
this.version = version;
|
|
61
71
|
this.chainId = chainId;
|
|
62
72
|
this.authwits = authwits;
|
|
63
|
-
this.
|
|
73
|
+
this.taggingSecretStrategies = taggingSecretStrategies;
|
|
74
|
+
this.authorizeAllUtilityCallTargets = authorizeAllUtilityCallTargets;
|
|
75
|
+
this.artifactResolver = artifactResolver;
|
|
76
|
+
this.rootPath = rootPath;
|
|
77
|
+
this.packageName = packageName;
|
|
64
78
|
this.isMisc = true;
|
|
65
79
|
this.isTxe = true;
|
|
66
80
|
this.logger = createLogger('txe:top_level_context');
|
|
67
81
|
this.logger.debug('Entering Top Level Context');
|
|
68
82
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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})`);
|
|
72
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;
|
|
73
97
|
}
|
|
74
98
|
// This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
|
|
75
99
|
// setup.
|
|
@@ -77,7 +101,7 @@ export class TXEOracleTopLevelContext {
|
|
|
77
101
|
return Fr.random();
|
|
78
102
|
}
|
|
79
103
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
80
|
-
log(level, message, fields) {
|
|
104
|
+
log(level, message, _fieldsSize, fields) {
|
|
81
105
|
if (!LogLevels[level]) {
|
|
82
106
|
throw new Error(`Invalid log level: ${level}`);
|
|
83
107
|
}
|
|
@@ -97,20 +121,27 @@ export class TXEOracleTopLevelContext {
|
|
|
97
121
|
return Promise.resolve(this.nextBlockTimestamp);
|
|
98
122
|
}
|
|
99
123
|
async getLastBlockTimestamp() {
|
|
100
|
-
return (await this.stateMachine.node.
|
|
124
|
+
return (await this.stateMachine.node.getBlockData('latest')).header.globalVariables.timestamp;
|
|
101
125
|
}
|
|
102
126
|
async getLastTxEffects() {
|
|
103
127
|
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
104
|
-
const block = await this.stateMachine.archiver.getBlock(
|
|
128
|
+
const block = await this.stateMachine.archiver.getBlock({
|
|
129
|
+
number: latestBlockNumber
|
|
130
|
+
});
|
|
105
131
|
if (block.body.txEffects.length != 1) {
|
|
106
132
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
107
133
|
throw new Error(`Expected a single transaction in the last block, found ${block.body.txEffects.length}`);
|
|
108
134
|
}
|
|
109
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
|
+
}
|
|
110
140
|
return {
|
|
111
141
|
txHash: txEffects.txHash,
|
|
112
142
|
noteHashes: txEffects.noteHashes,
|
|
113
|
-
nullifiers: txEffects.nullifiers
|
|
143
|
+
nullifiers: txEffects.nullifiers,
|
|
144
|
+
privateLogs
|
|
114
145
|
};
|
|
115
146
|
}
|
|
116
147
|
async syncContractNonOracleMethod(contractAddress, scope, jobId) {
|
|
@@ -118,15 +149,26 @@ export class TXEOracleTopLevelContext {
|
|
|
118
149
|
this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
|
|
119
150
|
return;
|
|
120
151
|
}
|
|
121
|
-
const
|
|
122
|
-
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
152
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
153
|
+
await this.stateMachine.contractSyncService.ensureContractSynced({
|
|
154
|
+
contract: contractAddress,
|
|
155
|
+
functionToInvokeAfterSync: null,
|
|
156
|
+
utilityExecutor: async (call, execScopes)=>{
|
|
157
|
+
await this.executeUtilityCall(call, {
|
|
158
|
+
scopes: execScopes,
|
|
159
|
+
jobId
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
anchorBlockHeader,
|
|
163
|
+
jobId,
|
|
164
|
+
scopes: [
|
|
165
|
+
scope
|
|
166
|
+
],
|
|
167
|
+
triggeredBy: undefined
|
|
168
|
+
});
|
|
127
169
|
}
|
|
128
170
|
async getPrivateEvents(selector, contractAddress, scope) {
|
|
129
|
-
|
|
171
|
+
const events = (await this.privateEventStore.getPrivateEvents(selector, {
|
|
130
172
|
contractAddress,
|
|
131
173
|
scopes: [
|
|
132
174
|
scope
|
|
@@ -134,6 +176,13 @@ export class TXEOracleTopLevelContext {
|
|
|
134
176
|
fromBlock: 0,
|
|
135
177
|
toBlock: await this.getLastBlockNumber() + 1
|
|
136
178
|
})).map((e)=>e.packedEvent);
|
|
179
|
+
if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
|
|
180
|
+
throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
|
|
181
|
+
}
|
|
182
|
+
if (events.some((e)=>e.length > MAX_PRIVATE_EVENT_LEN)) {
|
|
183
|
+
throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
|
|
184
|
+
}
|
|
185
|
+
return events;
|
|
137
186
|
}
|
|
138
187
|
async advanceBlocksBy(blocks) {
|
|
139
188
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
@@ -145,35 +194,59 @@ export class TXEOracleTopLevelContext {
|
|
|
145
194
|
this.logger.debug(`time traveling ${duration} seconds`);
|
|
146
195
|
this.nextBlockTimestamp += duration;
|
|
147
196
|
}
|
|
148
|
-
|
|
197
|
+
deploymentNullifier(address) {
|
|
198
|
+
return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
|
|
199
|
+
}
|
|
200
|
+
async deploy(contractPath, initializer, args, secret, salt, deployer) {
|
|
201
|
+
const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
|
|
202
|
+
rootPath: this.rootPath,
|
|
203
|
+
packageName: this.packageName,
|
|
204
|
+
contractPath,
|
|
205
|
+
initializer,
|
|
206
|
+
args,
|
|
207
|
+
secret,
|
|
208
|
+
salt,
|
|
209
|
+
deployer
|
|
210
|
+
});
|
|
149
211
|
// Emit deployment nullifier
|
|
150
212
|
await this.mineBlock({
|
|
151
213
|
nullifiers: [
|
|
152
|
-
await
|
|
214
|
+
await this.deploymentNullifier(instance.address)
|
|
153
215
|
]
|
|
154
216
|
});
|
|
155
217
|
if (!secret.equals(Fr.ZERO)) {
|
|
156
|
-
await this.
|
|
218
|
+
await this.registerContractAndAddAccount(artifact, instance, secret);
|
|
157
219
|
} else {
|
|
158
220
|
await this.contractStore.addContractInstance(instance);
|
|
159
221
|
await this.contractStore.addContractArtifact(artifact);
|
|
160
222
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
161
223
|
}
|
|
224
|
+
return CONTRACT_INSTANCE.serialization.fn(instance).flat();
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
|
|
228
|
+
*/ async mineDeploymentNullifiers(addresses) {
|
|
229
|
+
await this.mineBlock({
|
|
230
|
+
nullifiers: await Promise.all(addresses.map((address)=>this.deploymentNullifier(address)))
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
async addAccount(secret) {
|
|
234
|
+
const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
|
|
235
|
+
return this.registerContractAndAddAccount(artifact, instance, secret);
|
|
162
236
|
}
|
|
163
|
-
async
|
|
237
|
+
async registerContractAndAddAccount(artifact, instance, secret) {
|
|
164
238
|
const partialAddress = await computePartialAddress(instance);
|
|
165
239
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
166
240
|
await this.contractStore.addContractInstance(instance);
|
|
167
241
|
await this.contractStore.addContractArtifact(artifact);
|
|
168
|
-
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
242
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
169
243
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
170
244
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
171
245
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
172
246
|
return completeAddress;
|
|
173
247
|
}
|
|
174
|
-
async createAccount(secret) {
|
|
175
|
-
|
|
176
|
-
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
248
|
+
async createAccount(secret, partialAddress) {
|
|
249
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
177
250
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
178
251
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
179
252
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -181,14 +254,39 @@ export class TXEOracleTopLevelContext {
|
|
|
181
254
|
}
|
|
182
255
|
async addAuthWitness(address, messageHash) {
|
|
183
256
|
const account = await this.accountStore.getAccount(address);
|
|
184
|
-
const
|
|
257
|
+
const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
|
|
258
|
+
const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
|
|
185
259
|
const schnorr = new Schnorr();
|
|
186
|
-
const signature = await schnorr.constructSignature(messageHash
|
|
187
|
-
const authWitness = new AuthWitness(messageHash,
|
|
188
|
-
...signature.toBuffer()
|
|
189
|
-
]);
|
|
260
|
+
const signature = await schnorr.constructSignature(messageHash, privateKey);
|
|
261
|
+
const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
|
|
190
262
|
this.authwits.set(authWitness.requestHash.toString(), authWitness);
|
|
191
263
|
}
|
|
264
|
+
setTaggingSecretStrategies(unconstrainedStrategy, constrainedStrategy) {
|
|
265
|
+
const apply = (mode, strategy)=>{
|
|
266
|
+
if (strategy.isSome()) {
|
|
267
|
+
this.taggingSecretStrategies.set(mode, strategy.value);
|
|
268
|
+
} else {
|
|
269
|
+
this.taggingSecretStrategies.delete(mode);
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
apply(AppTaggingSecretKind.UNCONSTRAINED, unconstrainedStrategy);
|
|
273
|
+
apply(AppTaggingSecretKind.CONSTRAINED, constrainedStrategy);
|
|
274
|
+
}
|
|
275
|
+
setAuthorizeAllUtilityCallTargets(authorizeAll) {
|
|
276
|
+
this.authorizeAllUtilityCallTargets = authorizeAll;
|
|
277
|
+
}
|
|
278
|
+
async sendL1ToL2Message(content, secretHash, sender, recipient) {
|
|
279
|
+
// Messages are appended to the tree, so the next free slot is simply the current tree size.
|
|
280
|
+
const { size } = await this.stateMachine.synchronizer.getCommitted().getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
|
|
281
|
+
const leafIndex = new Fr(size);
|
|
282
|
+
const message = new L1ToL2Message(new L1Actor(sender, this.chainId.toNumber()), new L2Actor(recipient, this.version.toNumber()), content, secretHash, leafIndex);
|
|
283
|
+
await this.mineBlock({
|
|
284
|
+
l1ToL2Messages: [
|
|
285
|
+
message.hash()
|
|
286
|
+
]
|
|
287
|
+
});
|
|
288
|
+
return leafIndex;
|
|
289
|
+
}
|
|
192
290
|
async mineBlock(options = {}) {
|
|
193
291
|
const blockNumber = await this.getNextBlockNumber();
|
|
194
292
|
const txEffect = TxEffect.empty();
|
|
@@ -198,7 +296,7 @@ export class TXEOracleTopLevelContext {
|
|
|
198
296
|
];
|
|
199
297
|
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
200
298
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
201
|
-
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
299
|
+
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
|
|
202
300
|
const globals = makeGlobalVariables(undefined, {
|
|
203
301
|
blockNumber,
|
|
204
302
|
timestamp: this.nextBlockTimestamp,
|
|
@@ -210,31 +308,40 @@ export class TXEOracleTopLevelContext {
|
|
|
210
308
|
]);
|
|
211
309
|
await forkedWorldTrees.close();
|
|
212
310
|
this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
|
|
213
|
-
await this.stateMachine.handleL2Block(block);
|
|
311
|
+
await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
|
|
214
312
|
}
|
|
215
|
-
async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, jobId) {
|
|
216
|
-
|
|
217
|
-
const
|
|
313
|
+
async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, additionalScopes = [], jobId, authorizedUtilityCallTargets, gasSettings) {
|
|
314
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
315
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
|
|
316
|
+
this.logger.verbose(`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
|
|
317
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
218
318
|
if (!artifact) {
|
|
219
319
|
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';
|
|
220
320
|
throw new Error(message);
|
|
221
321
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
from
|
|
322
|
+
const scopes = from === undefined ? additionalScopes : [
|
|
323
|
+
from,
|
|
324
|
+
...additionalScopes
|
|
226
325
|
];
|
|
227
326
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
228
327
|
const utilityExecutor = async (call, execScopes)=>{
|
|
229
|
-
await this.executeUtilityCall(call,
|
|
328
|
+
await this.executeUtilityCall(call, {
|
|
329
|
+
scopes: execScopes,
|
|
330
|
+
jobId
|
|
331
|
+
});
|
|
230
332
|
};
|
|
231
|
-
|
|
232
|
-
|
|
333
|
+
await this.stateMachine.contractSyncService.ensureContractSynced({
|
|
334
|
+
contract: targetContractAddress,
|
|
335
|
+
functionToInvokeAfterSync: functionSelector,
|
|
336
|
+
utilityExecutor,
|
|
337
|
+
anchorBlockHeader: blockHeader,
|
|
338
|
+
jobId,
|
|
339
|
+
scopes,
|
|
340
|
+
triggeredBy: undefined
|
|
341
|
+
});
|
|
233
342
|
const blockNumber = await this.getNextBlockNumber();
|
|
234
|
-
const
|
|
235
|
-
const
|
|
236
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
237
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
343
|
+
const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
|
|
344
|
+
const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
|
|
238
345
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
239
346
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
240
347
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
@@ -245,9 +352,12 @@ export class TXEOracleTopLevelContext {
|
|
|
245
352
|
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
246
353
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
247
354
|
const simulator = new WASMSimulator();
|
|
355
|
+
const transientArrayService = new TransientArrayService();
|
|
248
356
|
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
249
357
|
argsHash,
|
|
250
358
|
txContext,
|
|
359
|
+
// The TXE does not run the init kernel's salt binding, so no tx-request salt is in scope.
|
|
360
|
+
txRequestSalt: Fr.ZERO,
|
|
251
361
|
callContext,
|
|
252
362
|
anchorBlockHeader: blockHeader,
|
|
253
363
|
utilityExecutor,
|
|
@@ -258,26 +368,33 @@ export class TXEOracleTopLevelContext {
|
|
|
258
368
|
]),
|
|
259
369
|
noteCache,
|
|
260
370
|
taggingIndexCache,
|
|
261
|
-
|
|
371
|
+
anchoredContractData,
|
|
262
372
|
noteStore: this.noteStore,
|
|
263
373
|
keyStore: this.keyStore,
|
|
264
374
|
addressStore: this.addressStore,
|
|
265
375
|
aztecNode: this.stateMachine.node,
|
|
266
376
|
senderTaggingStore: this.senderTaggingStore,
|
|
267
377
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
268
|
-
|
|
269
|
-
|
|
378
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
379
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
380
|
+
factService: new FactService(this.factStore, scopes),
|
|
270
381
|
privateEventStore: this.privateEventStore,
|
|
271
382
|
contractSyncService: this.stateMachine.contractSyncService,
|
|
272
383
|
jobId,
|
|
273
384
|
totalPublicCalldataCount: 0,
|
|
274
385
|
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
275
|
-
scopes
|
|
386
|
+
scopes,
|
|
276
387
|
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
277
388
|
// contract would perform, including setting senderForTags.
|
|
278
389
|
senderForTags: from,
|
|
279
390
|
simulator,
|
|
280
|
-
|
|
391
|
+
txResolver: this.stateMachine.txResolver,
|
|
392
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
393
|
+
hooks: composeHooks({
|
|
394
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(isStaticCall ? 'private view' : 'private', authorizedUtilityCallTargets),
|
|
395
|
+
resolveTaggingSecretStrategy: makeResolveTaggingSecretStrategyHook(this.taggingSecretStrategies)
|
|
396
|
+
}),
|
|
397
|
+
transientArrayService
|
|
281
398
|
});
|
|
282
399
|
// 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.
|
|
283
400
|
let result;
|
|
@@ -290,10 +407,9 @@ export class TXEOracleTopLevelContext {
|
|
|
290
407
|
r.publicInputs.publicTeardownCallRequest
|
|
291
408
|
]));
|
|
292
409
|
const publicFunctionsCalldata = await Promise.all(publicCallRequests.map(async (r)=>{
|
|
293
|
-
const calldata = await privateExecutionOracle.
|
|
410
|
+
const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
|
|
294
411
|
return new HashedValues(calldata, r.calldataHash);
|
|
295
412
|
}));
|
|
296
|
-
noteCache.finish();
|
|
297
413
|
const nonceGenerator = noteCache.getNonceGenerator();
|
|
298
414
|
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
299
415
|
} catch (err) {
|
|
@@ -302,7 +418,7 @@ export class TXEOracleTopLevelContext {
|
|
|
302
418
|
// According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
|
|
303
419
|
// the nonce generator for the note hashes.
|
|
304
420
|
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
305
|
-
const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>
|
|
421
|
+
const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>anchoredContractData.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
|
|
306
422
|
const globals = makeGlobalVariables();
|
|
307
423
|
globals.blockNumber = blockNumber;
|
|
308
424
|
globals.timestamp = this.nextBlockTimestamp;
|
|
@@ -341,7 +457,7 @@ export class TXEOracleTopLevelContext {
|
|
|
341
457
|
} else if (!processedTx.revertCode.isOK()) {
|
|
342
458
|
if (processedTx.revertReason) {
|
|
343
459
|
try {
|
|
344
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
460
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, await this.stateMachine.anchorBlockStore.getBlockHeader(), this.logger);
|
|
345
461
|
// eslint-disable-next-line no-empty
|
|
346
462
|
} catch {}
|
|
347
463
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -349,10 +465,20 @@ export class TXEOracleTopLevelContext {
|
|
|
349
465
|
throw new Error('Contract execution has reverted');
|
|
350
466
|
}
|
|
351
467
|
}
|
|
468
|
+
// Walk the nested private-call tree and collect every offchain effect the transaction emitted.
|
|
469
|
+
// PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
|
|
470
|
+
// `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
|
|
471
|
+
// we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
|
|
472
|
+
const offchainEffects = collectNested([
|
|
473
|
+
executionResult
|
|
474
|
+
], (r)=>r.offchainEffects.map((e)=>e.data));
|
|
352
475
|
if (isStaticCall) {
|
|
353
476
|
await checkpoint.revert();
|
|
354
477
|
await forkedWorldTrees.close();
|
|
355
|
-
return
|
|
478
|
+
return {
|
|
479
|
+
returnValues: executionResult.returnValues ?? [],
|
|
480
|
+
offchainEffects
|
|
481
|
+
};
|
|
356
482
|
}
|
|
357
483
|
const txEffect = TxEffect.empty();
|
|
358
484
|
txEffect.noteHashes = processedTx.txEffect.noteHashes;
|
|
@@ -368,16 +494,17 @@ export class TXEOracleTopLevelContext {
|
|
|
368
494
|
]);
|
|
369
495
|
await this.stateMachine.handleL2Block(l2Block);
|
|
370
496
|
await forkedWorldTrees.close();
|
|
371
|
-
return
|
|
497
|
+
return {
|
|
498
|
+
returnValues: executionResult.returnValues ?? [],
|
|
499
|
+
offchainEffects
|
|
500
|
+
};
|
|
372
501
|
}
|
|
373
|
-
async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall) {
|
|
374
|
-
|
|
502
|
+
async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall, gasSettings) {
|
|
503
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
504
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
|
|
505
|
+
this.logger.verbose(`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
|
|
375
506
|
const blockNumber = await this.getNextBlockNumber();
|
|
376
|
-
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
377
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
378
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
379
507
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
380
|
-
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
381
508
|
const calldataHash = await computeCalldataHash(calldata);
|
|
382
509
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
383
510
|
const globals = makeGlobalVariables();
|
|
@@ -408,7 +535,7 @@ export class TXEOracleTopLevelContext {
|
|
|
408
535
|
// The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
|
|
409
536
|
// may require producing reverts.
|
|
410
537
|
const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
411
|
-
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from, targetContractAddress, isStaticCall, calldataHash);
|
|
538
|
+
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from ?? AztecAddress.NULL_MSG_SENDER, targetContractAddress, isStaticCall, calldataHash);
|
|
412
539
|
const inputsForPublic = new PartialPrivateTailPublicInputsForPublic(nonRevertibleAccumulatedData, revertibleAccumulatedData, PublicCallRequest.empty());
|
|
413
540
|
const constantData = new TxConstantData(anchorBlockHeader, txContext, Fr.zero(), Fr.zero());
|
|
414
541
|
const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*expirationTimestamp=*/ 0n, inputsForPublic, undefined);
|
|
@@ -434,7 +561,7 @@ export class TXEOracleTopLevelContext {
|
|
|
434
561
|
} else if (!processedTx.revertCode.isOK()) {
|
|
435
562
|
if (processedTx.revertReason) {
|
|
436
563
|
try {
|
|
437
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
564
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader, this.logger);
|
|
438
565
|
// eslint-disable-next-line no-empty
|
|
439
566
|
} catch {}
|
|
440
567
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -464,16 +591,28 @@ export class TXEOracleTopLevelContext {
|
|
|
464
591
|
await forkedWorldTrees.close();
|
|
465
592
|
return returnValues ?? [];
|
|
466
593
|
}
|
|
467
|
-
async executeUtilityFunction(targetContractAddress, functionSelector, args, jobId) {
|
|
468
|
-
const
|
|
594
|
+
async executeUtilityFunction(from, targetContractAddress, functionSelector, args, jobId, authorizedUtilityCallTargets) {
|
|
595
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
596
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
|
|
597
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
469
598
|
if (!artifact) {
|
|
470
599
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
471
600
|
}
|
|
472
601
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
602
|
+
await this.stateMachine.contractSyncService.ensureContractSynced({
|
|
603
|
+
contract: targetContractAddress,
|
|
604
|
+
functionToInvokeAfterSync: functionSelector,
|
|
605
|
+
utilityExecutor: async (call, execScopes)=>{
|
|
606
|
+
await this.executeUtilityCall(call, {
|
|
607
|
+
scopes: execScopes,
|
|
608
|
+
jobId
|
|
609
|
+
});
|
|
610
|
+
},
|
|
611
|
+
anchorBlockHeader: blockHeader,
|
|
612
|
+
jobId,
|
|
613
|
+
scopes: await this.keyStore.getAccounts(),
|
|
614
|
+
triggeredBy: undefined
|
|
615
|
+
});
|
|
477
616
|
const call = FunctionCall.from({
|
|
478
617
|
name: artifact.name,
|
|
479
618
|
to: targetContractAddress,
|
|
@@ -484,10 +623,20 @@ export class TXEOracleTopLevelContext {
|
|
|
484
623
|
args,
|
|
485
624
|
returnTypes: []
|
|
486
625
|
});
|
|
487
|
-
return this.executeUtilityCall(call,
|
|
626
|
+
return this.executeUtilityCall(call, {
|
|
627
|
+
from,
|
|
628
|
+
scopes: await this.keyStore.getAccounts(),
|
|
629
|
+
jobId,
|
|
630
|
+
authorizedUtilityCallTargets
|
|
631
|
+
});
|
|
488
632
|
}
|
|
489
|
-
async executeUtilityCall(call, scopes, jobId) {
|
|
490
|
-
const
|
|
633
|
+
async executeUtilityCall(call, { from = AztecAddress.NULL_MSG_SENDER, scopes, jobId, authorizedUtilityCallTargets = [] }) {
|
|
634
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
635
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
|
|
636
|
+
const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
637
|
+
if (!entryPointArtifact) {
|
|
638
|
+
throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
|
|
639
|
+
}
|
|
491
640
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
492
641
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
493
642
|
}
|
|
@@ -496,27 +645,48 @@ export class TXEOracleTopLevelContext {
|
|
|
496
645
|
selector: call.selector
|
|
497
646
|
});
|
|
498
647
|
try {
|
|
499
|
-
const
|
|
648
|
+
const simulator = new WASMSimulator();
|
|
649
|
+
const utilityExecutor = async (syncCall, execScopes)=>{
|
|
650
|
+
await this.executeUtilityCall(syncCall, {
|
|
651
|
+
scopes: execScopes,
|
|
652
|
+
jobId,
|
|
653
|
+
authorizedUtilityCallTargets
|
|
654
|
+
});
|
|
655
|
+
};
|
|
500
656
|
const oracle = new UtilityExecutionOracle({
|
|
501
|
-
|
|
657
|
+
callContext: CallContext.from({
|
|
658
|
+
msgSender: from,
|
|
659
|
+
contractAddress: call.to,
|
|
660
|
+
functionSelector: call.selector,
|
|
661
|
+
isStaticCall: true
|
|
662
|
+
}),
|
|
502
663
|
authWitnesses: [],
|
|
503
664
|
capsules: [],
|
|
504
665
|
anchorBlockHeader,
|
|
505
|
-
|
|
666
|
+
anchoredContractData,
|
|
506
667
|
noteStore: this.noteStore,
|
|
507
668
|
keyStore: this.keyStore,
|
|
508
669
|
addressStore: this.addressStore,
|
|
509
670
|
aztecNode: this.stateMachine.node,
|
|
510
671
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
511
|
-
|
|
512
|
-
|
|
672
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
673
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
674
|
+
factService: new FactService(this.factStore, scopes),
|
|
513
675
|
privateEventStore: this.privateEventStore,
|
|
514
|
-
|
|
515
|
-
contractSyncService: this.contractSyncService,
|
|
676
|
+
txResolver: this.stateMachine.txResolver,
|
|
677
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
678
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
516
679
|
jobId,
|
|
517
|
-
scopes
|
|
680
|
+
scopes,
|
|
681
|
+
simulator,
|
|
682
|
+
utilityExecutor,
|
|
683
|
+
hooks: composeHooks({
|
|
684
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets)
|
|
685
|
+
}),
|
|
686
|
+
// Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
|
|
687
|
+
transientArrayService: new TransientArrayService()
|
|
518
688
|
});
|
|
519
|
-
const acirExecutionResult = await
|
|
689
|
+
const acirExecutionResult = await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle)).catch((err)=>{
|
|
520
690
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
521
691
|
throw new ExecutionError(err.message, {
|
|
522
692
|
contractAddress: call.to,
|
|
@@ -533,13 +703,33 @@ export class TXEOracleTopLevelContext {
|
|
|
533
703
|
}
|
|
534
704
|
close() {
|
|
535
705
|
this.logger.debug('Exiting Top Level Context');
|
|
536
|
-
return
|
|
537
|
-
this.nextBlockTimestamp,
|
|
538
|
-
this.authwits
|
|
539
|
-
|
|
706
|
+
return {
|
|
707
|
+
nextBlockTimestamp: this.nextBlockTimestamp,
|
|
708
|
+
authwits: this.authwits,
|
|
709
|
+
taggingSecretStrategies: this.taggingSecretStrategies,
|
|
710
|
+
authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets
|
|
711
|
+
};
|
|
540
712
|
}
|
|
541
713
|
async getLastBlockNumber() {
|
|
542
|
-
const
|
|
543
|
-
return
|
|
714
|
+
const block = await this.stateMachine.node.getBlock('latest');
|
|
715
|
+
return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
716
|
+
}
|
|
717
|
+
buildAuthorizeUtilityCallHook(callerContext, authorizedTargets) {
|
|
718
|
+
if (this.authorizeAllUtilityCallTargets) {
|
|
719
|
+
return authorizeAllUtilityCallsHook;
|
|
720
|
+
}
|
|
721
|
+
if (authorizedTargets.length === 0) {
|
|
722
|
+
return undefined;
|
|
723
|
+
}
|
|
724
|
+
return (req)=>Promise.resolve({
|
|
725
|
+
authorized: req.callerContext === callerContext && authorizedTargets.some((t)=>t.equals(req.target))
|
|
726
|
+
});
|
|
544
727
|
}
|
|
545
728
|
}
|
|
729
|
+
/**
|
|
730
|
+
* An `authorizeUtilityCall` hook that authorizes every cross-contract utility call.
|
|
731
|
+
*
|
|
732
|
+
* Backs the `aztec_txe_setAuthorizeAllUtilityCallTargets` oracle.
|
|
733
|
+
*/ export const authorizeAllUtilityCallsHook = ()=>Promise.resolve({
|
|
734
|
+
authorized: true
|
|
735
|
+
});
|