@aztec/txe 0.0.1-commit.343b43af6 → 0.0.1-commit.350e0a4d
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-2RDAZOGB.js +3 -0
- package/dest/AuthRegistry-2RDAZOGB.js.map +7 -0
- package/dest/ContractClassRegistry-L5F3G33N.js +3 -0
- package/dest/ContractClassRegistry-L5F3G33N.js.map +7 -0
- package/dest/ContractInstanceRegistry-IJOBAWAC.js +3 -0
- package/dest/ContractInstanceRegistry-IJOBAWAC.js.map +7 -0
- package/dest/FeeJuice-J3XDQPFS.js +3 -0
- package/dest/FeeJuice-J3XDQPFS.js.map +7 -0
- package/dest/HandshakeRegistry-QGWZJYVS.js +3 -0
- package/dest/HandshakeRegistry-QGWZJYVS.js.map +7 -0
- package/dest/MultiCallEntrypoint-WZHPRFJ6.js +3 -0
- package/dest/MultiCallEntrypoint-WZHPRFJ6.js.map +7 -0
- package/dest/SchnorrAccount-II4XD6MI.js +3 -0
- package/dest/SchnorrAccount-II4XD6MI.js.map +7 -0
- package/dest/SchnorrInitializerlessAccount-FXIOXUQQ.js +3 -0
- package/dest/SchnorrInitializerlessAccount-FXIOXUQQ.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-OMH3BDML.js +304 -0
- package/dest/chunk-OMH3BDML.js.map +7 -0
- package/dest/chunk-R3ZWQEFL.js +260 -0
- package/dest/chunk-R3ZWQEFL.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 +38140 -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 +38 -8
- package/dest/oracle/interfaces.d.ts.map +1 -1
- 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 +169 -0
- package/dest/oracle/txe_oracle_registry.d.ts.map +1 -0
- package/dest/oracle/txe_oracle_registry.js +745 -0
- package/dest/oracle/txe_oracle_top_level_context.d.ts +43 -16
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +233 -86
- 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 +112 -227
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +769 -607
- 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 +11 -5
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +50 -10
- package/dest/state_machine/mock_epoch_cache.d.ts +16 -3
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +29 -2
- package/dest/state_machine/synchronizer.d.ts +9 -6
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +10 -6
- package/dest/txe_session.d.ts +89 -19
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +308 -60
- 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 +8 -7
- 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 +35 -7
- 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 +536 -0
- package/src/oracle/txe_oracle_top_level_context.ts +307 -98
- 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 +858 -866
- 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 +63 -28
- package/src/state_machine/mock_epoch_cache.ts +38 -3
- package/src/state_machine/synchronizer.ts +13 -7
- package/src/txe_session.ts +539 -74
- 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 -6
- 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_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,29 +1,31 @@
|
|
|
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
|
-
import {
|
|
10
|
+
import { GuardedMerkleTreeOperations, PublicContractsDB, PublicProcessor, PublicTxSimulator } from '@aztec/simulator/server';
|
|
11
11
|
import { FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
12
12
|
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 { L1Actor, L1ToL2Message, L2Actor } from '@aztec/stdlib/messaging';
|
|
19
21
|
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
20
22
|
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
21
23
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
22
24
|
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';
|
|
25
|
+
import { ForkCheckpoint } from '@aztec/world-state/native';
|
|
26
|
+
import { DEFAULT_ADDRESS, MAX_PRIVATE_EVENTS_PER_TXE_QUERY, MAX_PRIVATE_EVENT_LEN } from '../constants.js';
|
|
26
27
|
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
28
|
+
import { TXEPublicContractDataSource } from '../utils/txe_public_contract_data_source.js';
|
|
27
29
|
export class TXEOracleTopLevelContext {
|
|
28
30
|
stateMachine;
|
|
29
31
|
contractStore;
|
|
@@ -33,17 +35,22 @@ export class TXEOracleTopLevelContext {
|
|
|
33
35
|
accountStore;
|
|
34
36
|
senderTaggingStore;
|
|
35
37
|
recipientTaggingStore;
|
|
36
|
-
|
|
38
|
+
taggingSecretSourcesStore;
|
|
37
39
|
capsuleStore;
|
|
40
|
+
factStore;
|
|
38
41
|
privateEventStore;
|
|
39
42
|
nextBlockTimestamp;
|
|
40
43
|
version;
|
|
41
44
|
chainId;
|
|
42
45
|
authwits;
|
|
46
|
+
taggingSecretStrategy;
|
|
47
|
+
artifactResolver;
|
|
48
|
+
rootPath;
|
|
49
|
+
packageName;
|
|
43
50
|
isMisc;
|
|
44
51
|
isTxe;
|
|
45
52
|
logger;
|
|
46
|
-
constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore,
|
|
53
|
+
constructor(stateMachine, contractStore, noteStore, keyStore, addressStore, accountStore, senderTaggingStore, recipientTaggingStore, taggingSecretSourcesStore, capsuleStore, factStore, privateEventStore, nextBlockTimestamp, version, chainId, authwits, taggingSecretStrategy, artifactResolver, rootPath, packageName){
|
|
47
54
|
this.stateMachine = stateMachine;
|
|
48
55
|
this.contractStore = contractStore;
|
|
49
56
|
this.noteStore = noteStore;
|
|
@@ -52,22 +59,37 @@ export class TXEOracleTopLevelContext {
|
|
|
52
59
|
this.accountStore = accountStore;
|
|
53
60
|
this.senderTaggingStore = senderTaggingStore;
|
|
54
61
|
this.recipientTaggingStore = recipientTaggingStore;
|
|
55
|
-
this.
|
|
62
|
+
this.taggingSecretSourcesStore = taggingSecretSourcesStore;
|
|
56
63
|
this.capsuleStore = capsuleStore;
|
|
64
|
+
this.factStore = factStore;
|
|
57
65
|
this.privateEventStore = privateEventStore;
|
|
58
66
|
this.nextBlockTimestamp = nextBlockTimestamp;
|
|
59
67
|
this.version = version;
|
|
60
68
|
this.chainId = chainId;
|
|
61
69
|
this.authwits = authwits;
|
|
70
|
+
this.taggingSecretStrategy = taggingSecretStrategy;
|
|
71
|
+
this.artifactResolver = artifactResolver;
|
|
72
|
+
this.rootPath = rootPath;
|
|
73
|
+
this.packageName = packageName;
|
|
62
74
|
this.isMisc = true;
|
|
63
75
|
this.isTxe = true;
|
|
64
76
|
this.logger = createLogger('txe:top_level_context');
|
|
65
77
|
this.logger.debug('Entering Top Level Context');
|
|
66
78
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
79
|
+
contractOracleVersion;
|
|
80
|
+
assertCompatibleOracleVersion(major, minor) {
|
|
81
|
+
if (major !== ORACLE_VERSION_MAJOR) {
|
|
82
|
+
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.';
|
|
83
|
+
throw new Error(`Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`);
|
|
70
84
|
}
|
|
85
|
+
this.contractOracleVersion = {
|
|
86
|
+
major,
|
|
87
|
+
minor
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
// Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
|
|
91
|
+
nonOracleFunctionGetContractOracleVersion() {
|
|
92
|
+
return this.contractOracleVersion;
|
|
71
93
|
}
|
|
72
94
|
// This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
|
|
73
95
|
// setup.
|
|
@@ -75,7 +97,7 @@ export class TXEOracleTopLevelContext {
|
|
|
75
97
|
return Fr.random();
|
|
76
98
|
}
|
|
77
99
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
78
|
-
log(level, message, fields) {
|
|
100
|
+
log(level, message, _fieldsSize, fields) {
|
|
79
101
|
if (!LogLevels[level]) {
|
|
80
102
|
throw new Error(`Invalid log level: ${level}`);
|
|
81
103
|
}
|
|
@@ -95,20 +117,27 @@ export class TXEOracleTopLevelContext {
|
|
|
95
117
|
return Promise.resolve(this.nextBlockTimestamp);
|
|
96
118
|
}
|
|
97
119
|
async getLastBlockTimestamp() {
|
|
98
|
-
return (await this.stateMachine.node.
|
|
120
|
+
return (await this.stateMachine.node.getBlockData('latest')).header.globalVariables.timestamp;
|
|
99
121
|
}
|
|
100
122
|
async getLastTxEffects() {
|
|
101
123
|
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
102
|
-
const block = await this.stateMachine.archiver.getBlock(
|
|
124
|
+
const block = await this.stateMachine.archiver.getBlock({
|
|
125
|
+
number: latestBlockNumber
|
|
126
|
+
});
|
|
103
127
|
if (block.body.txEffects.length != 1) {
|
|
104
128
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
105
129
|
throw new Error(`Expected a single transaction in the last block, found ${block.body.txEffects.length}`);
|
|
106
130
|
}
|
|
107
131
|
const txEffects = block.body.txEffects[0];
|
|
132
|
+
const privateLogs = txEffects.privateLogs;
|
|
133
|
+
if (privateLogs.length > MAX_PRIVATE_LOGS_PER_TX) {
|
|
134
|
+
throw new Error(`${privateLogs.length} private logs exceed max ${MAX_PRIVATE_LOGS_PER_TX}`);
|
|
135
|
+
}
|
|
108
136
|
return {
|
|
109
137
|
txHash: txEffects.txHash,
|
|
110
138
|
noteHashes: txEffects.noteHashes,
|
|
111
|
-
nullifiers: txEffects.nullifiers
|
|
139
|
+
nullifiers: txEffects.nullifiers,
|
|
140
|
+
privateLogs
|
|
112
141
|
};
|
|
113
142
|
}
|
|
114
143
|
async syncContractNonOracleMethod(contractAddress, scope, jobId) {
|
|
@@ -118,13 +147,16 @@ export class TXEOracleTopLevelContext {
|
|
|
118
147
|
}
|
|
119
148
|
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
120
149
|
await this.stateMachine.contractSyncService.ensureContractSynced(contractAddress, null, async (call, execScopes)=>{
|
|
121
|
-
await this.executeUtilityCall(call,
|
|
150
|
+
await this.executeUtilityCall(call, {
|
|
151
|
+
scopes: execScopes,
|
|
152
|
+
jobId
|
|
153
|
+
});
|
|
122
154
|
}, blockHeader, jobId, [
|
|
123
155
|
scope
|
|
124
156
|
]);
|
|
125
157
|
}
|
|
126
158
|
async getPrivateEvents(selector, contractAddress, scope) {
|
|
127
|
-
|
|
159
|
+
const events = (await this.privateEventStore.getPrivateEvents(selector, {
|
|
128
160
|
contractAddress,
|
|
129
161
|
scopes: [
|
|
130
162
|
scope
|
|
@@ -132,6 +164,13 @@ export class TXEOracleTopLevelContext {
|
|
|
132
164
|
fromBlock: 0,
|
|
133
165
|
toBlock: await this.getLastBlockNumber() + 1
|
|
134
166
|
})).map((e)=>e.packedEvent);
|
|
167
|
+
if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
|
|
168
|
+
throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
|
|
169
|
+
}
|
|
170
|
+
if (events.some((e)=>e.length > MAX_PRIVATE_EVENT_LEN)) {
|
|
171
|
+
throw new Error(`Some private event has length larger than maxLen ${MAX_PRIVATE_EVENT_LEN}`);
|
|
172
|
+
}
|
|
173
|
+
return events;
|
|
135
174
|
}
|
|
136
175
|
async advanceBlocksBy(blocks) {
|
|
137
176
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
@@ -143,27 +182,52 @@ export class TXEOracleTopLevelContext {
|
|
|
143
182
|
this.logger.debug(`time traveling ${duration} seconds`);
|
|
144
183
|
this.nextBlockTimestamp += duration;
|
|
145
184
|
}
|
|
146
|
-
|
|
185
|
+
deploymentNullifier(address) {
|
|
186
|
+
return siloNullifier(AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS), address.toField());
|
|
187
|
+
}
|
|
188
|
+
async deploy(contractPath, initializer, args, secret, salt, deployer) {
|
|
189
|
+
const { artifact, instance } = await this.artifactResolver.resolveDeployArtifact({
|
|
190
|
+
rootPath: this.rootPath,
|
|
191
|
+
packageName: this.packageName,
|
|
192
|
+
contractPath,
|
|
193
|
+
initializer,
|
|
194
|
+
args,
|
|
195
|
+
secret,
|
|
196
|
+
salt,
|
|
197
|
+
deployer
|
|
198
|
+
});
|
|
147
199
|
// Emit deployment nullifier
|
|
148
200
|
await this.mineBlock({
|
|
149
201
|
nullifiers: [
|
|
150
|
-
await
|
|
202
|
+
await this.deploymentNullifier(instance.address)
|
|
151
203
|
]
|
|
152
204
|
});
|
|
153
205
|
if (!secret.equals(Fr.ZERO)) {
|
|
154
|
-
await this.
|
|
206
|
+
await this.registerContractAndAddAccount(artifact, instance, secret);
|
|
155
207
|
} else {
|
|
156
208
|
await this.contractStore.addContractInstance(instance);
|
|
157
209
|
await this.contractStore.addContractArtifact(artifact);
|
|
158
210
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
159
211
|
}
|
|
212
|
+
return CONTRACT_INSTANCE.serialization.fn(instance).flat();
|
|
160
213
|
}
|
|
161
|
-
|
|
214
|
+
/**
|
|
215
|
+
* Mines a single block containing only the deployment nullifiers for the contracts at the given addresses.
|
|
216
|
+
*/ async mineDeploymentNullifiers(addresses) {
|
|
217
|
+
await this.mineBlock({
|
|
218
|
+
nullifiers: await Promise.all(addresses.map((address)=>this.deploymentNullifier(address)))
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
async addAccount(secret) {
|
|
222
|
+
const { artifact, instance } = await this.artifactResolver.resolveAccountArtifact(secret);
|
|
223
|
+
return this.registerContractAndAddAccount(artifact, instance, secret);
|
|
224
|
+
}
|
|
225
|
+
async registerContractAndAddAccount(artifact, instance, secret) {
|
|
162
226
|
const partialAddress = await computePartialAddress(instance);
|
|
163
227
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
164
228
|
await this.contractStore.addContractInstance(instance);
|
|
165
229
|
await this.contractStore.addContractArtifact(artifact);
|
|
166
|
-
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
230
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), partialAddress);
|
|
167
231
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
168
232
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
169
233
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -171,7 +235,7 @@ export class TXEOracleTopLevelContext {
|
|
|
171
235
|
}
|
|
172
236
|
async createAccount(secret) {
|
|
173
237
|
// This is a foot gun !
|
|
174
|
-
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
238
|
+
const completeAddress = await this.keyStore.addAccount(await deriveKeys(secret), secret);
|
|
175
239
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
176
240
|
await this.addressStore.addCompleteAddress(completeAddress);
|
|
177
241
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
@@ -179,14 +243,28 @@ export class TXEOracleTopLevelContext {
|
|
|
179
243
|
}
|
|
180
244
|
async addAuthWitness(address, messageHash) {
|
|
181
245
|
const account = await this.accountStore.getAccount(address);
|
|
182
|
-
const
|
|
246
|
+
const ivpkMHash = await hashPublicKey(account.publicKeys.ivpkM);
|
|
247
|
+
const privateKey = await this.keyStore.getMasterSecretKey(ivpkMHash);
|
|
183
248
|
const schnorr = new Schnorr();
|
|
184
|
-
const signature = await schnorr.constructSignature(messageHash
|
|
185
|
-
const authWitness = new AuthWitness(messageHash,
|
|
186
|
-
...signature.toBuffer()
|
|
187
|
-
]);
|
|
249
|
+
const signature = await schnorr.constructSignature(messageHash, privateKey);
|
|
250
|
+
const authWitness = new AuthWitness(messageHash, signature.toLimbFields());
|
|
188
251
|
this.authwits.set(authWitness.requestHash.toString(), authWitness);
|
|
189
252
|
}
|
|
253
|
+
setTaggingSecretStrategy(strategy) {
|
|
254
|
+
this.taggingSecretStrategy = strategy.value;
|
|
255
|
+
}
|
|
256
|
+
async sendL1ToL2Message(content, secretHash, sender, recipient) {
|
|
257
|
+
// Messages are appended to the tree, so the next free slot is simply the current tree size.
|
|
258
|
+
const { size } = await this.stateMachine.synchronizer.getCommitted().getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
|
|
259
|
+
const leafIndex = new Fr(size);
|
|
260
|
+
const message = new L1ToL2Message(new L1Actor(sender, this.chainId.toNumber()), new L2Actor(recipient, this.version.toNumber()), content, secretHash, leafIndex);
|
|
261
|
+
await this.mineBlock({
|
|
262
|
+
l1ToL2Messages: [
|
|
263
|
+
message.hash()
|
|
264
|
+
]
|
|
265
|
+
});
|
|
266
|
+
return leafIndex;
|
|
267
|
+
}
|
|
190
268
|
async mineBlock(options = {}) {
|
|
191
269
|
const blockNumber = await this.getNextBlockNumber();
|
|
192
270
|
const txEffect = TxEffect.empty();
|
|
@@ -196,7 +274,7 @@ export class TXEOracleTopLevelContext {
|
|
|
196
274
|
];
|
|
197
275
|
txEffect.txHash = new TxHash(new Fr(blockNumber));
|
|
198
276
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
199
|
-
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
277
|
+
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees, options.l1ToL2Messages ?? []);
|
|
200
278
|
const globals = makeGlobalVariables(undefined, {
|
|
201
279
|
blockNumber,
|
|
202
280
|
timestamp: this.nextBlockTimestamp,
|
|
@@ -208,31 +286,32 @@ export class TXEOracleTopLevelContext {
|
|
|
208
286
|
]);
|
|
209
287
|
await forkedWorldTrees.close();
|
|
210
288
|
this.logger.info(`Created block ${blockNumber} with timestamp ${block.header.globalVariables.timestamp}`);
|
|
211
|
-
await this.stateMachine.handleL2Block(block);
|
|
289
|
+
await this.stateMachine.handleL2Block(block, options.l1ToL2Messages ?? []);
|
|
212
290
|
}
|
|
213
|
-
async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, jobId) {
|
|
214
|
-
|
|
215
|
-
const
|
|
291
|
+
async privateCallNewFlow(from, targetContractAddress = AztecAddress.zero(), functionSelector = FunctionSelector.empty(), args, argsHash = Fr.zero(), isStaticCall = false, additionalScopes = [], jobId, authorizedUtilityCallTargets, gasSettings) {
|
|
292
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
293
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
|
|
294
|
+
this.logger.verbose(`Executing external function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`);
|
|
295
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
216
296
|
if (!artifact) {
|
|
217
297
|
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';
|
|
218
298
|
throw new Error(message);
|
|
219
299
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
from
|
|
300
|
+
const scopes = from === undefined ? additionalScopes : [
|
|
301
|
+
from,
|
|
302
|
+
...additionalScopes
|
|
224
303
|
];
|
|
225
304
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
226
305
|
const utilityExecutor = async (call, execScopes)=>{
|
|
227
|
-
await this.executeUtilityCall(call,
|
|
306
|
+
await this.executeUtilityCall(call, {
|
|
307
|
+
scopes: execScopes,
|
|
308
|
+
jobId
|
|
309
|
+
});
|
|
228
310
|
};
|
|
229
|
-
|
|
230
|
-
await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, effectiveScopes);
|
|
311
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, utilityExecutor, blockHeader, jobId, scopes);
|
|
231
312
|
const blockNumber = await this.getNextBlockNumber();
|
|
232
|
-
const
|
|
233
|
-
const
|
|
234
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
235
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
313
|
+
const msgSender = from ?? AztecAddress.NULL_MSG_SENDER;
|
|
314
|
+
const callContext = new CallContext(msgSender, targetContractAddress, functionSelector, isStaticCall);
|
|
236
315
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
237
316
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
238
317
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
@@ -243,9 +322,12 @@ export class TXEOracleTopLevelContext {
|
|
|
243
322
|
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
244
323
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
245
324
|
const simulator = new WASMSimulator();
|
|
325
|
+
const transientArrayService = new TransientArrayService();
|
|
326
|
+
const taggingSecretStrategy = this.taggingSecretStrategy;
|
|
246
327
|
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
247
328
|
argsHash,
|
|
248
329
|
txContext,
|
|
330
|
+
txRequestSalt: Fr.ZERO,
|
|
249
331
|
callContext,
|
|
250
332
|
anchorBlockHeader: blockHeader,
|
|
251
333
|
utilityExecutor,
|
|
@@ -256,25 +338,35 @@ export class TXEOracleTopLevelContext {
|
|
|
256
338
|
]),
|
|
257
339
|
noteCache,
|
|
258
340
|
taggingIndexCache,
|
|
259
|
-
|
|
341
|
+
anchoredContractData,
|
|
260
342
|
noteStore: this.noteStore,
|
|
261
343
|
keyStore: this.keyStore,
|
|
262
344
|
addressStore: this.addressStore,
|
|
263
345
|
aztecNode: this.stateMachine.node,
|
|
264
346
|
senderTaggingStore: this.senderTaggingStore,
|
|
265
347
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
266
|
-
|
|
267
|
-
|
|
348
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
349
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
350
|
+
factService: new FactService(this.factStore, scopes),
|
|
268
351
|
privateEventStore: this.privateEventStore,
|
|
269
352
|
contractSyncService: this.stateMachine.contractSyncService,
|
|
270
353
|
jobId,
|
|
271
354
|
totalPublicCalldataCount: 0,
|
|
272
355
|
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
273
|
-
scopes
|
|
356
|
+
scopes,
|
|
274
357
|
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
275
358
|
// contract would perform, including setting senderForTags.
|
|
276
359
|
senderForTags: from,
|
|
277
|
-
simulator
|
|
360
|
+
simulator,
|
|
361
|
+
txResolver: this.stateMachine.txResolver,
|
|
362
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
363
|
+
hooks: composeHooks({
|
|
364
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook(isStaticCall ? 'private view' : 'private', authorizedUtilityCallTargets),
|
|
365
|
+
// Only configure the hook when a strategy was explicitly set, so that otherwise the default tagging secret
|
|
366
|
+
// strategy is exercised.
|
|
367
|
+
resolveTaggingSecretStrategy: taggingSecretStrategy ? ()=>Promise.resolve(taggingSecretStrategy) : undefined
|
|
368
|
+
}),
|
|
369
|
+
transientArrayService
|
|
278
370
|
});
|
|
279
371
|
// 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.
|
|
280
372
|
let result;
|
|
@@ -287,10 +379,9 @@ export class TXEOracleTopLevelContext {
|
|
|
287
379
|
r.publicInputs.publicTeardownCallRequest
|
|
288
380
|
]));
|
|
289
381
|
const publicFunctionsCalldata = await Promise.all(publicCallRequests.map(async (r)=>{
|
|
290
|
-
const calldata = await privateExecutionOracle.
|
|
382
|
+
const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
|
|
291
383
|
return new HashedValues(calldata, r.calldataHash);
|
|
292
384
|
}));
|
|
293
|
-
noteCache.finish();
|
|
294
385
|
const nonceGenerator = noteCache.getNonceGenerator();
|
|
295
386
|
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
296
387
|
} catch (err) {
|
|
@@ -299,7 +390,7 @@ export class TXEOracleTopLevelContext {
|
|
|
299
390
|
// According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
|
|
300
391
|
// the nonce generator for the note hashes.
|
|
301
392
|
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
302
|
-
const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>
|
|
393
|
+
const { publicInputs } = await generateSimulatedProvingResult(result, (addr, sel)=>anchoredContractData.getDebugFunctionName(addr, sel), this.stateMachine.node, minRevertibleSideEffectCounter);
|
|
303
394
|
const globals = makeGlobalVariables();
|
|
304
395
|
globals.blockNumber = blockNumber;
|
|
305
396
|
globals.timestamp = this.nextBlockTimestamp;
|
|
@@ -317,7 +408,7 @@ export class TXEOracleTopLevelContext {
|
|
|
317
408
|
collectStatistics: false,
|
|
318
409
|
collectCallMetadata: true
|
|
319
410
|
});
|
|
320
|
-
const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new
|
|
411
|
+
const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings), new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings));
|
|
321
412
|
const tx = await Tx.create({
|
|
322
413
|
data: publicInputs,
|
|
323
414
|
chonkProof: ChonkProof.empty(),
|
|
@@ -338,7 +429,7 @@ export class TXEOracleTopLevelContext {
|
|
|
338
429
|
} else if (!processedTx.revertCode.isOK()) {
|
|
339
430
|
if (processedTx.revertReason) {
|
|
340
431
|
try {
|
|
341
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
432
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, await this.stateMachine.anchorBlockStore.getBlockHeader(), this.logger);
|
|
342
433
|
// eslint-disable-next-line no-empty
|
|
343
434
|
} catch {}
|
|
344
435
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -346,10 +437,20 @@ export class TXEOracleTopLevelContext {
|
|
|
346
437
|
throw new Error('Contract execution has reverted');
|
|
347
438
|
}
|
|
348
439
|
}
|
|
440
|
+
// Walk the nested private-call tree and collect every offchain effect the transaction emitted.
|
|
441
|
+
// PXE stores these on each `PrivateCallExecutionResult` and they never reach TXE via the
|
|
442
|
+
// `aztec_utl_emitOffchainEffect` foreign-call path (that path only fires at the top-level), so
|
|
443
|
+
// we pull them out here and the RPC wrapper will hand them to `TXESession` for buffering.
|
|
444
|
+
const offchainEffects = collectNested([
|
|
445
|
+
executionResult
|
|
446
|
+
], (r)=>r.offchainEffects.map((e)=>e.data));
|
|
349
447
|
if (isStaticCall) {
|
|
350
448
|
await checkpoint.revert();
|
|
351
449
|
await forkedWorldTrees.close();
|
|
352
|
-
return
|
|
450
|
+
return {
|
|
451
|
+
returnValues: executionResult.returnValues ?? [],
|
|
452
|
+
offchainEffects
|
|
453
|
+
};
|
|
353
454
|
}
|
|
354
455
|
const txEffect = TxEffect.empty();
|
|
355
456
|
txEffect.noteHashes = processedTx.txEffect.noteHashes;
|
|
@@ -365,16 +466,17 @@ export class TXEOracleTopLevelContext {
|
|
|
365
466
|
]);
|
|
366
467
|
await this.stateMachine.handleL2Block(l2Block);
|
|
367
468
|
await forkedWorldTrees.close();
|
|
368
|
-
return
|
|
469
|
+
return {
|
|
470
|
+
returnValues: executionResult.returnValues ?? [],
|
|
471
|
+
offchainEffects
|
|
472
|
+
};
|
|
369
473
|
}
|
|
370
|
-
async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall) {
|
|
371
|
-
|
|
474
|
+
async publicCallNewFlow(from, targetContractAddress, calldata, isStaticCall, gasSettings) {
|
|
475
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
476
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
|
|
477
|
+
this.logger.verbose(`Executing public function ${await anchoredContractData.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`);
|
|
372
478
|
const blockNumber = await this.getNextBlockNumber();
|
|
373
|
-
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
374
|
-
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
375
|
-
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
376
479
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
377
|
-
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
378
480
|
const calldataHash = await computeCalldataHash(calldata);
|
|
379
481
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
380
482
|
const globals = makeGlobalVariables();
|
|
@@ -394,7 +496,7 @@ export class TXEOracleTopLevelContext {
|
|
|
394
496
|
collectStatistics: false,
|
|
395
497
|
collectCallMetadata: true
|
|
396
498
|
});
|
|
397
|
-
const simulator = new
|
|
499
|
+
const simulator = new PublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
|
|
398
500
|
const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider(), undefined, createLogger('simulator:public-processor', bindings2));
|
|
399
501
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
400
502
|
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
@@ -405,7 +507,7 @@ export class TXEOracleTopLevelContext {
|
|
|
405
507
|
// The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
|
|
406
508
|
// may require producing reverts.
|
|
407
509
|
const revertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
408
|
-
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from, targetContractAddress, isStaticCall, calldataHash);
|
|
510
|
+
revertibleAccumulatedData.publicCallRequests[0] = new PublicCallRequest(from ?? AztecAddress.NULL_MSG_SENDER, targetContractAddress, isStaticCall, calldataHash);
|
|
409
511
|
const inputsForPublic = new PartialPrivateTailPublicInputsForPublic(nonRevertibleAccumulatedData, revertibleAccumulatedData, PublicCallRequest.empty());
|
|
410
512
|
const constantData = new TxConstantData(anchorBlockHeader, txContext, Fr.zero(), Fr.zero());
|
|
411
513
|
const txData = new PrivateKernelTailCircuitPublicInputs(constantData, /*gasUsed=*/ new Gas(0, 0), /*feePayer=*/ AztecAddress.zero(), /*expirationTimestamp=*/ 0n, inputsForPublic, undefined);
|
|
@@ -431,7 +533,7 @@ export class TXEOracleTopLevelContext {
|
|
|
431
533
|
} else if (!processedTx.revertCode.isOK()) {
|
|
432
534
|
if (processedTx.revertReason) {
|
|
433
535
|
try {
|
|
434
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
536
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader, this.logger);
|
|
435
537
|
// eslint-disable-next-line no-empty
|
|
436
538
|
} catch {}
|
|
437
539
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -461,16 +563,20 @@ export class TXEOracleTopLevelContext {
|
|
|
461
563
|
await forkedWorldTrees.close();
|
|
462
564
|
return returnValues ?? [];
|
|
463
565
|
}
|
|
464
|
-
async executeUtilityFunction(targetContractAddress, functionSelector, args, jobId) {
|
|
465
|
-
const
|
|
566
|
+
async executeUtilityFunction(from, targetContractAddress, functionSelector, args, jobId, authorizedUtilityCallTargets) {
|
|
567
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
568
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, blockHeader);
|
|
569
|
+
const artifact = await anchoredContractData.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
466
570
|
if (!artifact) {
|
|
467
571
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
468
572
|
}
|
|
469
573
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
470
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
471
574
|
await this.stateMachine.contractSyncService.ensureContractSynced(targetContractAddress, functionSelector, async (call, execScopes)=>{
|
|
472
|
-
await this.executeUtilityCall(call,
|
|
473
|
-
|
|
575
|
+
await this.executeUtilityCall(call, {
|
|
576
|
+
scopes: execScopes,
|
|
577
|
+
jobId
|
|
578
|
+
});
|
|
579
|
+
}, blockHeader, jobId, await this.keyStore.getAccounts());
|
|
474
580
|
const call = FunctionCall.from({
|
|
475
581
|
name: artifact.name,
|
|
476
582
|
to: targetContractAddress,
|
|
@@ -481,10 +587,20 @@ export class TXEOracleTopLevelContext {
|
|
|
481
587
|
args,
|
|
482
588
|
returnTypes: []
|
|
483
589
|
});
|
|
484
|
-
return this.executeUtilityCall(call,
|
|
590
|
+
return this.executeUtilityCall(call, {
|
|
591
|
+
from,
|
|
592
|
+
scopes: await this.keyStore.getAccounts(),
|
|
593
|
+
jobId,
|
|
594
|
+
authorizedUtilityCallTargets
|
|
595
|
+
});
|
|
485
596
|
}
|
|
486
|
-
async executeUtilityCall(call, scopes, jobId) {
|
|
487
|
-
const
|
|
597
|
+
async executeUtilityCall(call, { from = AztecAddress.NULL_MSG_SENDER, scopes, jobId, authorizedUtilityCallTargets = [] }) {
|
|
598
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
599
|
+
const anchoredContractData = new AnchoredContractData(this.contractStore, this.stateMachine.contractClassService, anchorBlockHeader);
|
|
600
|
+
const entryPointArtifact = await anchoredContractData.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
601
|
+
if (!entryPointArtifact) {
|
|
602
|
+
throw new Error(`Cannot run function ${call.selector} on ${call.to}: the contract is not registered.`);
|
|
603
|
+
}
|
|
488
604
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
489
605
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
490
606
|
}
|
|
@@ -493,25 +609,47 @@ export class TXEOracleTopLevelContext {
|
|
|
493
609
|
selector: call.selector
|
|
494
610
|
});
|
|
495
611
|
try {
|
|
496
|
-
const
|
|
612
|
+
const simulator = new WASMSimulator();
|
|
613
|
+
const utilityExecutor = async (syncCall, execScopes)=>{
|
|
614
|
+
await this.executeUtilityCall(syncCall, {
|
|
615
|
+
scopes: execScopes,
|
|
616
|
+
jobId
|
|
617
|
+
});
|
|
618
|
+
};
|
|
497
619
|
const oracle = new UtilityExecutionOracle({
|
|
498
|
-
|
|
620
|
+
callContext: CallContext.from({
|
|
621
|
+
msgSender: from,
|
|
622
|
+
contractAddress: call.to,
|
|
623
|
+
functionSelector: call.selector,
|
|
624
|
+
isStaticCall: true
|
|
625
|
+
}),
|
|
499
626
|
authWitnesses: [],
|
|
500
627
|
capsules: [],
|
|
501
628
|
anchorBlockHeader,
|
|
502
|
-
|
|
629
|
+
anchoredContractData,
|
|
503
630
|
noteStore: this.noteStore,
|
|
504
631
|
keyStore: this.keyStore,
|
|
505
632
|
addressStore: this.addressStore,
|
|
506
633
|
aztecNode: this.stateMachine.node,
|
|
507
634
|
recipientTaggingStore: this.recipientTaggingStore,
|
|
508
|
-
|
|
509
|
-
|
|
635
|
+
taggingSecretSourcesStore: this.taggingSecretSourcesStore,
|
|
636
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
637
|
+
factService: new FactService(this.factStore, scopes),
|
|
510
638
|
privateEventStore: this.privateEventStore,
|
|
639
|
+
txResolver: this.stateMachine.txResolver,
|
|
640
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
641
|
+
l2TipsStore: this.stateMachine.l2TipsProvider,
|
|
511
642
|
jobId,
|
|
512
|
-
scopes
|
|
643
|
+
scopes,
|
|
644
|
+
simulator,
|
|
645
|
+
hooks: composeHooks({
|
|
646
|
+
authorizeUtilityCall: this.buildAuthorizeUtilityCallHook('utility', authorizedUtilityCallTargets)
|
|
647
|
+
}),
|
|
648
|
+
utilityExecutor,
|
|
649
|
+
// Execution-tree root (top-level utility run or contract sync): own store; nested frames inherit it.
|
|
650
|
+
transientArrayService: new TransientArrayService()
|
|
513
651
|
});
|
|
514
|
-
const acirExecutionResult = await
|
|
652
|
+
const acirExecutionResult = await simulator.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, buildACIRCallback(oracle)).catch((err)=>{
|
|
515
653
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
516
654
|
throw new ExecutionError(err.message, {
|
|
517
655
|
contractAddress: call.to,
|
|
@@ -530,11 +668,20 @@ export class TXEOracleTopLevelContext {
|
|
|
530
668
|
this.logger.debug('Exiting Top Level Context');
|
|
531
669
|
return [
|
|
532
670
|
this.nextBlockTimestamp,
|
|
533
|
-
this.authwits
|
|
671
|
+
this.authwits,
|
|
672
|
+
this.taggingSecretStrategy
|
|
534
673
|
];
|
|
535
674
|
}
|
|
536
675
|
async getLastBlockNumber() {
|
|
537
|
-
const
|
|
538
|
-
return
|
|
676
|
+
const block = await this.stateMachine.node.getBlock('latest');
|
|
677
|
+
return block ? block.header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
678
|
+
}
|
|
679
|
+
buildAuthorizeUtilityCallHook(callerContext, authorizedTargets) {
|
|
680
|
+
if (authorizedTargets.length === 0) {
|
|
681
|
+
return undefined;
|
|
682
|
+
}
|
|
683
|
+
return (req)=>Promise.resolve({
|
|
684
|
+
authorized: req.callerContext === callerContext && authorizedTargets.some((t)=>t.equals(req.target))
|
|
685
|
+
});
|
|
539
686
|
}
|
|
540
687
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The TXE oracle version constants are used to check that the oracle interface used for tests is in sync between
|
|
3
|
+
* TXE and Aztec.nr. This is separate from the contract oracle version in `pxe/src/oracle_version.ts`, which covers
|
|
4
|
+
* oracles used during contract execution by PXE.
|
|
5
|
+
*
|
|
6
|
+
* The Noir counterparts are in `noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const TXE_ORACLE_VERSION_MAJOR = 2;
|
|
9
|
+
export declare const TXE_ORACLE_VERSION_MINOR = 3;
|
|
10
|
+
/**
|
|
11
|
+
* This hash is computed from the TXE oracle interfaces (IAvmExecutionOracle and ITxeExecutionOracle) and is used to
|
|
12
|
+
* detect when those interfaces change. When it does, bump:
|
|
13
|
+
* - TXE_ORACLE_VERSION_MAJOR (and reset MINOR to 0) for breaking changes, or
|
|
14
|
+
* - TXE_ORACLE_VERSION_MINOR for additive changes (new oracle method added).
|
|
15
|
+
*/
|
|
16
|
+
export declare const TXE_ORACLE_INTERFACE_HASH = "4ed3618087fafb4aa63c6580996a69bf6bc257844035a2019692586b5b8daf34";
|
|
17
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhlX29yYWNsZV92ZXJzaW9uLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb3JhY2xlL3R4ZV9vcmFjbGVfdmVyc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFDSCxlQUFPLE1BQU0sd0JBQXdCLElBQUksQ0FBQztBQUMxQyxlQUFPLE1BQU0sd0JBQXdCLElBQUksQ0FBQztBQUUxQzs7Ozs7R0FLRztBQUNILGVBQU8sTUFBTSx5QkFBeUIscUVBQXFFLENBQUMifQ==
|