@aztec/txe 0.0.1-commit.42ee6df9b → 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 +286 -97
- 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 -647
- 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 +25 -16
- package/dest/state_machine/dummy_p2p_client.d.ts +16 -7
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +26 -2
- 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 +313 -67
- 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 +357 -118
- 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 +890 -938
- package/src/state_machine/archiver.ts +37 -17
- package/src/state_machine/dummy_p2p_client.ts +43 -10
- package/src/state_machine/global_variable_builder.ts +12 -17
- 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 +545 -80
- 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 { CapsuleService,
|
|
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,24 +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
|
-
|
|
72
|
-
|
|
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})`);
|
|
73
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;
|
|
74
97
|
}
|
|
75
98
|
// This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
|
|
76
99
|
// setup.
|
|
@@ -78,7 +101,7 @@ export class TXEOracleTopLevelContext {
|
|
|
78
101
|
return Fr.random();
|
|
79
102
|
}
|
|
80
103
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
81
|
-
log(level, message, fields) {
|
|
104
|
+
log(level, message, _fieldsSize, fields) {
|
|
82
105
|
if (!LogLevels[level]) {
|
|
83
106
|
throw new Error(`Invalid log level: ${level}`);
|
|
84
107
|
}
|
|
@@ -98,20 +121,27 @@ export class TXEOracleTopLevelContext {
|
|
|
98
121
|
return Promise.resolve(this.nextBlockTimestamp);
|
|
99
122
|
}
|
|
100
123
|
async getLastBlockTimestamp() {
|
|
101
|
-
return (await this.stateMachine.node.
|
|
124
|
+
return (await this.stateMachine.node.getBlockData('latest')).header.globalVariables.timestamp;
|
|
102
125
|
}
|
|
103
126
|
async getLastTxEffects() {
|
|
104
127
|
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
105
|
-
const block = await this.stateMachine.archiver.getBlock(
|
|
128
|
+
const block = await this.stateMachine.archiver.getBlock({
|
|
129
|
+
number: latestBlockNumber
|
|
130
|
+
});
|
|
106
131
|
if (block.body.txEffects.length != 1) {
|
|
107
132
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
108
133
|
throw new Error(`Expected a single transaction in the last block, found ${block.body.txEffects.length}`);
|
|
109
134
|
}
|
|
110
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
|
+
}
|
|
111
140
|
return {
|
|
112
141
|
txHash: txEffects.txHash,
|
|
113
142
|
noteHashes: txEffects.noteHashes,
|
|
114
|
-
nullifiers: txEffects.nullifiers
|
|
143
|
+
nullifiers: txEffects.nullifiers,
|
|
144
|
+
privateLogs
|
|
115
145
|
};
|
|
116
146
|
}
|
|
117
147
|
async syncContractNonOracleMethod(contractAddress, scope, jobId) {
|
|
@@ -119,15 +149,26 @@ export class TXEOracleTopLevelContext {
|
|
|
119
149
|
this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
|
|
120
150
|
return;
|
|
121
151
|
}
|
|
122
|
-
const
|
|
123
|
-
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
+
});
|
|
128
169
|
}
|
|
129
170
|
async getPrivateEvents(selector, contractAddress, scope) {
|
|
130
|
-
|
|
171
|
+
const events = (await this.privateEventStore.getPrivateEvents(selector, {
|
|
131
172
|
contractAddress,
|
|
132
173
|
scopes: [
|
|
133
174
|
scope
|
|
@@ -135,6 +176,13 @@ export class TXEOracleTopLevelContext {
|
|
|
135
176
|
fromBlock: 0,
|
|
136
177
|
toBlock: await this.getLastBlockNumber() + 1
|
|
137
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;
|
|
138
186
|
}
|
|
139
187
|
async advanceBlocksBy(blocks) {
|
|
140
188
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
@@ -146,35 +194,59 @@ export class TXEOracleTopLevelContext {
|
|
|
146
194
|
this.logger.debug(`time traveling ${duration} seconds`);
|
|
147
195
|
this.nextBlockTimestamp += duration;
|
|
148
196
|
}
|
|
149
|
-
|
|
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
|
+
});
|
|
150
211
|
// Emit deployment nullifier
|
|
151
212
|
await this.mineBlock({
|
|
152
213
|
nullifiers: [
|
|
153
|
-
await
|
|
214
|
+
await this.deploymentNullifier(instance.address)
|
|
154
215
|
]
|
|
155
216
|
});
|
|
156
217
|
if (!secret.equals(Fr.ZERO)) {
|
|
157
|
-
await this.
|
|
218
|
+
await this.registerContractAndAddAccount(artifact, instance, secret);
|
|
158
219
|
} else {
|
|
159
220
|
await this.contractStore.addContractInstance(instance);
|
|
160
221
|
await this.contractStore.addContractArtifact(artifact);
|
|
161
222
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
162
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);
|
|
163
236
|
}
|
|
164
|
-
async
|
|
237
|
+
async registerContractAndAddAccount(artifact, instance, secret) {
|
|
165
238
|
const partialAddress = await computePartialAddress(instance);
|
|
166
239
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
167
240
|
await this.contractStore.addContractInstance(instance);
|
|
168
241
|
await this.contractStore.addContractArtifact(artifact);
|
|
169
|
-
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
242
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
170
243
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
171
244
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
172
245
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
173
246
|
return completeAddress;
|
|
174
247
|
}
|
|
175
|
-
async createAccount(secret) {
|
|
176
|
-
|
|
177
|
-
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
248
|
+
async createAccount(secret, partialAddress) {
|
|
249
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
178
250
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
179
251
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
180
252
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -182,14 +254,39 @@ export class TXEOracleTopLevelContext {
|
|
|
182
254
|
}
|
|
183
255
|
async addAuthWitness(address, messageHash) {
|
|
184
256
|
const account = await this.accountStore.getAccount(address);
|
|
185
|
-
const
|
|
257
|
+
const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
|
|
258
|
+
const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
|
|
186
259
|
const schnorr = new Schnorr();
|
|
187
|
-
const signature = await schnorr.constructSignature(messageHash
|
|
188
|
-
const authWitness = new AuthWitness(messageHash,
|
|
189
|
-
...signature.toBuffer()
|
|
190
|
-
]);
|
|
260
|
+
const signature = await schnorr.constructSignature(messageHash, privateKey);
|
|
261
|
+
const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
|
|
191
262
|
this.authwits.set(authWitness.requestHash.toString(), authWitness);
|
|
192
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
|
+
}
|
|
193
290
|
async mineBlock(options = {}) {
|
|
194
291
|
const blockNumber = await this.getNextBlockNumber();
|
|
195
292
|
const txEffect = TxEffect.empty();
|
|
@@ -199,7 +296,7 @@ export class TXEOracleTopLevelContext {
|
|
|
199
296
|
];
|
|
200
297
|
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
201
298
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
202
|
-
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
299
|
+
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
|
|
203
300
|
const globals = makeGlobalVariables(undefined, {
|
|
204
301
|
blockNumber,
|
|
205
302
|
timestamp: this.nextBlockTimestamp,
|
|
@@ -211,31 +308,40 @@ export class TXEOracleTopLevelContext {
|
|
|
211
308
|
]);
|
|
212
309
|
await forkedWorldTrees.close();
|
|
213
310
|
this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
|
|
214
|
-
await this.stateMachine.handleL2Block(block);
|
|
311
|
+
await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
|
|
215
312
|
}
|
|
216
|
-
async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, jobId) {
|
|
217
|
-
|
|
218
|
-
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);
|
|
219
318
|
if (!artifact) {
|
|
220
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';
|
|
221
320
|
throw new Error(message);
|
|
222
321
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
from
|
|
322
|
+
const scopes = from === undefined ? additionalScopes : [
|
|
323
|
+
from,
|
|
324
|
+
...additionalScopes
|
|
227
325
|
];
|
|
228
326
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
229
327
|
const utilityExecutor = async (call, execScopes)=>{
|
|
230
|
-
await this.executeUtilityCall(call,
|
|
328
|
+
await this.executeUtilityCall(call, {
|
|
329
|
+
scopes: execScopes,
|
|
330
|
+
jobId
|
|
331
|
+
});
|
|
231
332
|
};
|
|
232
|
-
|
|
233
|
-
|
|
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
|
+
});
|
|
234
342
|
const blockNumber = await this.getNextBlockNumber();
|
|
235
|
-
const
|
|
236
|
-
const
|
|
237
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
238
|
-
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);
|
|
239
345
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
240
346
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
241
347
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
@@ -246,9 +352,12 @@ export class TXEOracleTopLevelContext {
|
|
|
246
352
|
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
247
353
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
248
354
|
const simulator = new WASMSimulator();
|
|
355
|
+
const transientArrayService = new TransientArrayService();
|
|
249
356
|
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
250
357
|
argsHash,
|
|
251
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,
|
|
252
361
|
callContext,
|
|
253
362
|
anchorBlockHeader: blockHeader,
|
|
254
363
|
utilityExecutor,
|
|
@@ -259,26 +368,33 @@ export class TXEOracleTopLevelContext {
|
|
|
259
368
|
]),
|
|
260
369
|
noteCache,
|
|
261
370
|
taggingIndexCache,
|
|
262
|
-
|
|
371
|
+
anchoredContractData,
|
|
263
372
|
noteStore: this.noteStore,
|
|
264
373
|
keyStore: this.keyStore,
|
|
265
374
|
addressStore: this.addressStore,
|
|
266
375
|
aztecNode: this.stateMachine.node,
|
|
267
376
|
senderTaggingStore: this.senderTaggingStore,
|
|
268
377
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
269
|
-
|
|
270
|
-
capsuleService: new CapsuleService(this.capsuleStore,
|
|
378
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
379
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
380
|
+
factService: new FactService(this.factStore, scopes),
|
|
271
381
|
privateEventStore: this.privateEventStore,
|
|
272
382
|
contractSyncService: this.stateMachine.contractSyncService,
|
|
273
383
|
jobId,
|
|
274
384
|
totalPublicCalldataCount: 0,
|
|
275
385
|
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
276
|
-
scopes
|
|
386
|
+
scopes,
|
|
277
387
|
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
278
388
|
// contract would perform, including setting senderForTags.
|
|
279
389
|
senderForTags: from,
|
|
280
390
|
simulator,
|
|
281
|
-
|
|
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
|
|
282
398
|
});
|
|
283
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.
|
|
284
400
|
let result;
|
|
@@ -294,7 +410,6 @@ export class TXEOracleTopLevelContext {
|
|
|
294
410
|
const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
|
|
295
411
|
return new HashedValues(calldata, r.calldataHash);
|
|
296
412
|
}));
|
|
297
|
-
noteCache.finish();
|
|
298
413
|
const nonceGenerator = noteCache.getNonceGenerator();
|
|
299
414
|
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
300
415
|
} catch (err) {
|
|
@@ -303,7 +418,7 @@ export class TXEOracleTopLevelContext {
|
|
|
303
418
|
// According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
|
|
304
419
|
// the nonce generator for the note hashes.
|
|
305
420
|
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
306
|
-
const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>
|
|
421
|
+
const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>anchoredContractData.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
|
|
307
422
|
const globals = makeGlobalVariables();
|
|
308
423
|
globals.blockNumber = blockNumber;
|
|
309
424
|
globals.timestamp = this.nextBlockTimestamp;
|
|
@@ -342,7 +457,7 @@ export class TXEOracleTopLevelContext {
|
|
|
342
457
|
} else if (!processedTx.revertCode.isOK()) {
|
|
343
458
|
if (processedTx.revertReason) {
|
|
344
459
|
try {
|
|
345
|
-
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);
|
|
346
461
|
// eslint-disable-next-line no-empty
|
|
347
462
|
} catch {}
|
|
348
463
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -350,10 +465,20 @@ export class TXEOracleTopLevelContext {
|
|
|
350
465
|
throw new Error('Contract execution has reverted');
|
|
351
466
|
}
|
|
352
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));
|
|
353
475
|
if (isStaticCall) {
|
|
354
476
|
await checkpoint.revert();
|
|
355
477
|
await forkedWorldTrees.close();
|
|
356
|
-
return
|
|
478
|
+
return {
|
|
479
|
+
returnValues: executionResult.returnValues ?? [],
|
|
480
|
+
offchainEffects
|
|
481
|
+
};
|
|
357
482
|
}
|
|
358
483
|
const txEffect = TxEffect.empty();
|
|
359
484
|
txEffect.noteHashes = processedTx.txEffect.noteHashes;
|
|
@@ -369,16 +494,17 @@ export class TXEOracleTopLevelContext {
|
|
|
369
494
|
]);
|
|
370
495
|
await this.stateMachine.handleL2Block(l2Block);
|
|
371
496
|
await forkedWorldTrees.close();
|
|
372
|
-
return
|
|
497
|
+
return {
|
|
498
|
+
returnValues: executionResult.returnValues ?? [],
|
|
499
|
+
offchainEffects
|
|
500
|
+
};
|
|
373
501
|
}
|
|
374
|
-
async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall) {
|
|
375
|
-
|
|
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}`);
|
|
376
506
|
const blockNumber = await this.getNextBlockNumber();
|
|
377
|
-
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
378
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
379
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
380
507
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
381
|
-
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
382
508
|
const calldataHash = await computeCalldataHash(calldata);
|
|
383
509
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
384
510
|
const globals = makeGlobalVariables();
|
|
@@ -409,7 +535,7 @@ export class TXEOracleTopLevelContext {
|
|
|
409
535
|
// The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
|
|
410
536
|
// may require producing reverts.
|
|
411
537
|
const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
412
|
-
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from, targetContractAddress, isStaticCall, calldataHash);
|
|
538
|
+
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from ?? AztecAddress.NULL_MSG_SENDER, targetContractAddress, isStaticCall, calldataHash);
|
|
413
539
|
const inputsForPublic = new PartialPrivateTailPublicInputsForPublic(nonRevertibleAccumulatedData, revertibleAccumulatedData, PublicCallRequest.empty());
|
|
414
540
|
const constantData = new TxConstantData(anchorBlockHeader, txContext, Fr.zero(), Fr.zero());
|
|
415
541
|
const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*expirationTimestamp=*/ 0n, inputsForPublic, undefined);
|
|
@@ -435,7 +561,7 @@ export class TXEOracleTopLevelContext {
|
|
|
435
561
|
} else if (!processedTx.revertCode.isOK()) {
|
|
436
562
|
if (processedTx.revertReason) {
|
|
437
563
|
try {
|
|
438
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
564
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader, this.logger);
|
|
439
565
|
// eslint-disable-next-line no-empty
|
|
440
566
|
} catch {}
|
|
441
567
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -465,16 +591,28 @@ export class TXEOracleTopLevelContext {
|
|
|
465
591
|
await forkedWorldTrees.close();
|
|
466
592
|
return returnValues ?? [];
|
|
467
593
|
}
|
|
468
|
-
async executeUtilityFunction(targetContractAddress, functionSelector, args, jobId) {
|
|
469
|
-
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);
|
|
470
598
|
if (!artifact) {
|
|
471
599
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
472
600
|
}
|
|
473
601
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
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
|
+
});
|
|
478
616
|
const call = FunctionCall.from({
|
|
479
617
|
name: artifact.name,
|
|
480
618
|
to: targetContractAddress,
|
|
@@ -485,10 +623,20 @@ export class TXEOracleTopLevelContext {
|
|
|
485
623
|
args,
|
|
486
624
|
returnTypes: []
|
|
487
625
|
});
|
|
488
|
-
return this.executeUtilityCall(call,
|
|
626
|
+
return this.executeUtilityCall(call, {
|
|
627
|
+
from,
|
|
628
|
+
scopes: await this.keyStore.getAccounts(),
|
|
629
|
+
jobId,
|
|
630
|
+
authorizedUtilityCallTargets
|
|
631
|
+
});
|
|
489
632
|
}
|
|
490
|
-
async executeUtilityCall(call, scopes, jobId) {
|
|
491
|
-
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
|
+
}
|
|
492
640
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
493
641
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
494
642
|
}
|
|
@@ -497,27 +645,48 @@ export class TXEOracleTopLevelContext {
|
|
|
497
645
|
selector: call.selector
|
|
498
646
|
});
|
|
499
647
|
try {
|
|
500
|
-
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
|
+
};
|
|
501
656
|
const oracle = new UtilityExecutionOracle({
|
|
502
|
-
|
|
657
|
+
callContext: CallContext.from({
|
|
658
|
+
msgSender: from,
|
|
659
|
+
contractAddress: call.to,
|
|
660
|
+
functionSelector: call.selector,
|
|
661
|
+
isStaticCall: true
|
|
662
|
+
}),
|
|
503
663
|
authWitnesses: [],
|
|
504
664
|
capsules: [],
|
|
505
665
|
anchorBlockHeader,
|
|
506
|
-
|
|
666
|
+
anchoredContractData,
|
|
507
667
|
noteStore: this.noteStore,
|
|
508
668
|
keyStore: this.keyStore,
|
|
509
669
|
addressStore: this.addressStore,
|
|
510
670
|
aztecNode: this.stateMachine.node,
|
|
511
671
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
512
|
-
|
|
672
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
513
673
|
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
674
|
+
factService: new FactService(this.factStore, scopes),
|
|
514
675
|
privateEventStore: this.privateEventStore,
|
|
515
|
-
|
|
516
|
-
contractSyncService: this.contractSyncService,
|
|
676
|
+
txResolver: this.stateMachine.txResolver,
|
|
677
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
678
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
517
679
|
jobId,
|
|
518
|
-
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()
|
|
519
688
|
});
|
|
520
|
-
const acirExecutionResult = await
|
|
689
|
+
const acirExecutionResult = await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle)).catch((err)=>{
|
|
521
690
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
522
691
|
throw new ExecutionError(err.message, {
|
|
523
692
|
contractAddress: call.to,
|
|
@@ -534,13 +703,33 @@ export class TXEOracleTopLevelContext {
|
|
|
534
703
|
}
|
|
535
704
|
close() {
|
|
536
705
|
this.logger.debug('Exiting Top Level Context');
|
|
537
|
-
return
|
|
538
|
-
this.nextBlockTimestamp,
|
|
539
|
-
this.authwits
|
|
540
|
-
|
|
706
|
+
return {
|
|
707
|
+
nextBlockTimestamp: this.nextBlockTimestamp,
|
|
708
|
+
authwits: this.authwits,
|
|
709
|
+
taggingSecretStrategies: this.taggingSecretStrategies,
|
|
710
|
+
authorizeAllUtilityCallTargets: this.authorizeAllUtilityCallTargets
|
|
711
|
+
};
|
|
541
712
|
}
|
|
542
713
|
async getLastBlockNumber() {
|
|
543
|
-
const
|
|
544
|
-
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
|
+
});
|
|
545
727
|
}
|
|
546
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
|
+
});
|