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