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