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