@aztec/txe 0.0.1-commit.6d63667d → 0.0.1-commit.7b97ef96e
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/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +82 -50
- package/dest/oracle/interfaces.d.ts +2 -2
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.d.ts +5 -6
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +80 -28
- package/dest/rpc_translator.d.ts +5 -5
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +5 -5
- package/dest/state_machine/dummy_p2p_client.d.ts +15 -11
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +27 -15
- package/dest/state_machine/index.d.ts +1 -1
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +1 -1
- package/dest/state_machine/mock_epoch_cache.d.ts +3 -1
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +4 -0
- package/dest/txe_session.d.ts +4 -6
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +63 -14
- package/dest/util/txe_public_contract_data_source.d.ts +2 -3
- package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
- package/dest/util/txe_public_contract_data_source.js +5 -22
- package/package.json +15 -15
- package/src/index.ts +83 -49
- package/src/oracle/interfaces.ts +1 -1
- package/src/oracle/txe_oracle_top_level_context.ts +74 -81
- package/src/rpc_translator.ts +5 -5
- package/src/state_machine/dummy_p2p_client.ts +39 -21
- package/src/state_machine/index.ts +1 -0
- package/src/state_machine/mock_epoch_cache.ts +5 -0
- package/src/txe_session.ts +61 -64
- package/src/util/txe_public_contract_data_source.ts +10 -36
- package/dest/util/txe_contract_store.d.ts +0 -12
- package/dest/util/txe_contract_store.d.ts.map +0 -1
- package/dest/util/txe_contract_store.js +0 -22
- package/src/util/txe_contract_store.ts +0 -36
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/txe",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.7b97ef96e",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dest/index.js",
|
|
6
6
|
"bin": "./dest/bin/index.js",
|
|
@@ -61,20 +61,20 @@
|
|
|
61
61
|
]
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@aztec/accounts": "0.0.1-commit.
|
|
65
|
-
"@aztec/archiver": "0.0.1-commit.
|
|
66
|
-
"@aztec/aztec-node": "0.0.1-commit.
|
|
67
|
-
"@aztec/aztec.js": "0.0.1-commit.
|
|
68
|
-
"@aztec/bb-prover": "0.0.1-commit.
|
|
69
|
-
"@aztec/constants": "0.0.1-commit.
|
|
70
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
71
|
-
"@aztec/key-store": "0.0.1-commit.
|
|
72
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
73
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
74
|
-
"@aztec/pxe": "0.0.1-commit.
|
|
75
|
-
"@aztec/simulator": "0.0.1-commit.
|
|
76
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
77
|
-
"@aztec/world-state": "0.0.1-commit.
|
|
64
|
+
"@aztec/accounts": "0.0.1-commit.7b97ef96e",
|
|
65
|
+
"@aztec/archiver": "0.0.1-commit.7b97ef96e",
|
|
66
|
+
"@aztec/aztec-node": "0.0.1-commit.7b97ef96e",
|
|
67
|
+
"@aztec/aztec.js": "0.0.1-commit.7b97ef96e",
|
|
68
|
+
"@aztec/bb-prover": "0.0.1-commit.7b97ef96e",
|
|
69
|
+
"@aztec/constants": "0.0.1-commit.7b97ef96e",
|
|
70
|
+
"@aztec/foundation": "0.0.1-commit.7b97ef96e",
|
|
71
|
+
"@aztec/key-store": "0.0.1-commit.7b97ef96e",
|
|
72
|
+
"@aztec/kv-store": "0.0.1-commit.7b97ef96e",
|
|
73
|
+
"@aztec/protocol-contracts": "0.0.1-commit.7b97ef96e",
|
|
74
|
+
"@aztec/pxe": "0.0.1-commit.7b97ef96e",
|
|
75
|
+
"@aztec/simulator": "0.0.1-commit.7b97ef96e",
|
|
76
|
+
"@aztec/stdlib": "0.0.1-commit.7b97ef96e",
|
|
77
|
+
"@aztec/world-state": "0.0.1-commit.7b97ef96e",
|
|
78
78
|
"zod": "^3.23.8"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
package/src/index.ts
CHANGED
|
@@ -9,9 +9,12 @@ import { Fr } from '@aztec/aztec.js/fields';
|
|
|
9
9
|
import { PublicKeys, deriveKeys } from '@aztec/aztec.js/keys';
|
|
10
10
|
import { createSafeJsonRpcServer } from '@aztec/foundation/json-rpc/server';
|
|
11
11
|
import type { Logger } from '@aztec/foundation/log';
|
|
12
|
-
import {
|
|
12
|
+
import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
|
|
13
|
+
import { protocolContractNames } from '@aztec/protocol-contracts';
|
|
13
14
|
import { BundledProtocolContractsProvider } from '@aztec/protocol-contracts/providers/bundle';
|
|
15
|
+
import { ContractStore } from '@aztec/pxe/server';
|
|
14
16
|
import { computeArtifactHash } from '@aztec/stdlib/contract';
|
|
17
|
+
import type { ContractArtifactWithHash } from '@aztec/stdlib/contract';
|
|
15
18
|
import type { ApiSchemaFor } from '@aztec/stdlib/schemas';
|
|
16
19
|
import { zodFor } from '@aztec/stdlib/schemas';
|
|
17
20
|
|
|
@@ -33,18 +36,24 @@ import {
|
|
|
33
36
|
fromSingle,
|
|
34
37
|
toSingle,
|
|
35
38
|
} from './util/encoding.js';
|
|
36
|
-
import type { ContractArtifactWithHash } from './util/txe_contract_store.js';
|
|
37
39
|
|
|
38
40
|
const sessions = new Map<number, TXESession>();
|
|
39
41
|
|
|
40
42
|
/*
|
|
41
43
|
* TXE typically has to load the same contract artifacts over and over again for multiple tests,
|
|
42
|
-
* so we cache them here to avoid
|
|
44
|
+
* so we cache them here to avoid loading from disk repeatedly.
|
|
45
|
+
*
|
|
46
|
+
* The in-flight map coalesces concurrent requests for the same cache key so that
|
|
47
|
+
* computeArtifactHash (very expensive) is only run once even under parallelism.
|
|
43
48
|
*/
|
|
44
49
|
const TXEArtifactsCache = new Map<
|
|
45
50
|
string,
|
|
46
51
|
{ artifact: ContractArtifactWithHash; instance: ContractInstanceWithAddress }
|
|
47
52
|
>();
|
|
53
|
+
const TXEArtifactsCacheInFlight = new Map<
|
|
54
|
+
string,
|
|
55
|
+
Promise<{ artifact: ContractArtifactWithHash; instance: ContractInstanceWithAddress }>
|
|
56
|
+
>();
|
|
48
57
|
|
|
49
58
|
type TXEForeignCallInput = {
|
|
50
59
|
session_id: number;
|
|
@@ -68,7 +77,7 @@ const TXEForeignCallInputSchema = zodFor<TXEForeignCallInput>()(
|
|
|
68
77
|
);
|
|
69
78
|
|
|
70
79
|
class TXEDispatcher {
|
|
71
|
-
private
|
|
80
|
+
private contractStore!: ContractStore;
|
|
72
81
|
|
|
73
82
|
constructor(private logger: Logger) {}
|
|
74
83
|
|
|
@@ -135,29 +144,36 @@ class TXEDispatcher {
|
|
|
135
144
|
this.logger.debug(`Using cached artifact for ${cacheKey}`);
|
|
136
145
|
({ artifact, instance } = TXEArtifactsCache.get(cacheKey)!);
|
|
137
146
|
} else {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
147
|
+
if (!TXEArtifactsCacheInFlight.has(cacheKey)) {
|
|
148
|
+
this.logger.debug(`Loading compiled artifact ${artifactPath}`);
|
|
149
|
+
const compute = async () => {
|
|
150
|
+
const artifactJSON = JSON.parse(await readFile(artifactPath, 'utf-8')) as NoirCompiledContract;
|
|
151
|
+
const artifactWithoutHash = loadContractArtifact(artifactJSON);
|
|
152
|
+
const computedArtifact: ContractArtifactWithHash = {
|
|
153
|
+
...artifactWithoutHash,
|
|
154
|
+
// Artifact hash is *very* expensive to compute, so we do it here once
|
|
155
|
+
// and the TXE contract data provider can cache it
|
|
156
|
+
artifactHash: await computeArtifactHash(artifactWithoutHash),
|
|
157
|
+
};
|
|
158
|
+
this.logger.debug(
|
|
159
|
+
`Deploy ${computedArtifact.name} with initializer ${initializer}(${decodedArgs}) and public keys hash ${publicKeysHash.toString()}`,
|
|
160
|
+
);
|
|
161
|
+
const computedInstance = await getContractInstanceFromInstantiationParams(computedArtifact, {
|
|
162
|
+
constructorArgs: decodedArgs,
|
|
163
|
+
skipArgsDecoding: true,
|
|
164
|
+
salt: Fr.ONE,
|
|
165
|
+
publicKeys,
|
|
166
|
+
constructorArtifact: initializer ? initializer : undefined,
|
|
167
|
+
deployer: AztecAddress.ZERO,
|
|
168
|
+
});
|
|
169
|
+
const result = { artifact: computedArtifact, instance: computedInstance };
|
|
170
|
+
TXEArtifactsCache.set(cacheKey, result);
|
|
171
|
+
TXEArtifactsCacheInFlight.delete(cacheKey);
|
|
172
|
+
return result;
|
|
173
|
+
};
|
|
174
|
+
TXEArtifactsCacheInFlight.set(cacheKey, compute());
|
|
175
|
+
}
|
|
176
|
+
({ artifact, instance } = await TXEArtifactsCacheInFlight.get(cacheKey)!);
|
|
161
177
|
}
|
|
162
178
|
|
|
163
179
|
inputs.splice(0, 1, artifact, instance, toSingle(secret));
|
|
@@ -175,23 +191,35 @@ class TXEDispatcher {
|
|
|
175
191
|
this.logger.debug(`Using cached artifact for ${cacheKey}`);
|
|
176
192
|
({ artifact, instance } = TXEArtifactsCache.get(cacheKey)!);
|
|
177
193
|
} else {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
194
|
+
if (!TXEArtifactsCacheInFlight.has(cacheKey)) {
|
|
195
|
+
const compute = async () => {
|
|
196
|
+
const keys = await deriveKeys(secret);
|
|
197
|
+
const args = [
|
|
198
|
+
keys.publicKeys.masterIncomingViewingPublicKey.x,
|
|
199
|
+
keys.publicKeys.masterIncomingViewingPublicKey.y,
|
|
200
|
+
];
|
|
201
|
+
const computedArtifact: ContractArtifactWithHash = {
|
|
202
|
+
...SchnorrAccountContractArtifact,
|
|
203
|
+
// Artifact hash is *very* expensive to compute, so we do it here once
|
|
204
|
+
// and the TXE contract data provider can cache it
|
|
205
|
+
artifactHash: await computeArtifactHash(SchnorrAccountContractArtifact),
|
|
206
|
+
};
|
|
207
|
+
const computedInstance = await getContractInstanceFromInstantiationParams(computedArtifact, {
|
|
208
|
+
constructorArgs: args,
|
|
209
|
+
skipArgsDecoding: true,
|
|
210
|
+
salt: Fr.ONE,
|
|
211
|
+
publicKeys: keys.publicKeys,
|
|
212
|
+
constructorArtifact: 'constructor',
|
|
213
|
+
deployer: AztecAddress.ZERO,
|
|
214
|
+
});
|
|
215
|
+
const result = { artifact: computedArtifact, instance: computedInstance };
|
|
216
|
+
TXEArtifactsCache.set(cacheKey, result);
|
|
217
|
+
TXEArtifactsCacheInFlight.delete(cacheKey);
|
|
218
|
+
return result;
|
|
219
|
+
};
|
|
220
|
+
TXEArtifactsCacheInFlight.set(cacheKey, compute());
|
|
221
|
+
}
|
|
222
|
+
({ artifact, instance } = await TXEArtifactsCacheInFlight.get(cacheKey)!);
|
|
195
223
|
}
|
|
196
224
|
|
|
197
225
|
inputs.splice(0, 0, artifact, instance);
|
|
@@ -204,12 +232,18 @@ class TXEDispatcher {
|
|
|
204
232
|
|
|
205
233
|
if (!sessions.has(sessionId)) {
|
|
206
234
|
this.logger.debug(`Creating new session ${sessionId}`);
|
|
207
|
-
if (!this.
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
);
|
|
235
|
+
if (!this.contractStore) {
|
|
236
|
+
const kvStore = await openTmpStore('txe-contracts');
|
|
237
|
+
this.contractStore = new ContractStore(kvStore);
|
|
238
|
+
const provider = new BundledProtocolContractsProvider();
|
|
239
|
+
for (const name of protocolContractNames) {
|
|
240
|
+
const { instance, artifact } = await provider.getProtocolContractArtifact(name);
|
|
241
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
242
|
+
await this.contractStore.addContractInstance(instance);
|
|
243
|
+
}
|
|
244
|
+
this.logger.debug('Registered protocol contracts in shared contract store');
|
|
211
245
|
}
|
|
212
|
-
sessions.set(sessionId, await TXESession.init(this.
|
|
246
|
+
sessions.set(sessionId, await TXESession.init(this.contractStore));
|
|
213
247
|
}
|
|
214
248
|
|
|
215
249
|
switch (functionName) {
|
package/src/oracle/interfaces.ts
CHANGED
|
@@ -12,9 +12,11 @@ import { Fr } from '@aztec/foundation/curves/bn254';
|
|
|
12
12
|
import { LogLevels, type Logger, applyStringFormatting, createLogger } from '@aztec/foundation/log';
|
|
13
13
|
import { TestDateProvider } from '@aztec/foundation/timer';
|
|
14
14
|
import type { KeyStore } from '@aztec/key-store';
|
|
15
|
+
import type { AccessScopes } from '@aztec/pxe/client/lazy';
|
|
15
16
|
import {
|
|
16
17
|
AddressStore,
|
|
17
18
|
CapsuleStore,
|
|
19
|
+
type ContractStore,
|
|
18
20
|
NoteStore,
|
|
19
21
|
ORACLE_VERSION,
|
|
20
22
|
PrivateEventStore,
|
|
@@ -83,7 +85,6 @@ import { ForkCheckpoint } from '@aztec/world-state';
|
|
|
83
85
|
import { DEFAULT_ADDRESS } from '../constants.js';
|
|
84
86
|
import type { TXEStateMachine } from '../state_machine/index.js';
|
|
85
87
|
import type { TXEAccountStore } from '../util/txe_account_store.js';
|
|
86
|
-
import type { TXEContractStore } from '../util/txe_contract_store.js';
|
|
87
88
|
import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
|
|
88
89
|
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
89
90
|
import type { ITxeExecutionOracle } from './interfaces.js';
|
|
@@ -96,7 +97,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
96
97
|
|
|
97
98
|
constructor(
|
|
98
99
|
private stateMachine: TXEStateMachine,
|
|
99
|
-
private contractStore:
|
|
100
|
+
private contractStore: ContractStore,
|
|
100
101
|
private noteStore: NoteStore,
|
|
101
102
|
private keyStore: KeyStore,
|
|
102
103
|
private addressStore: AddressStore,
|
|
@@ -131,13 +132,14 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
134
|
-
|
|
135
|
+
utilityLog(level: number, message: string, fields: Fr[]): Promise<void> {
|
|
135
136
|
if (!LogLevels[level]) {
|
|
136
|
-
throw new Error(`Invalid
|
|
137
|
+
throw new Error(`Invalid log level: ${level}`);
|
|
137
138
|
}
|
|
138
139
|
const levelName = LogLevels[level];
|
|
139
140
|
|
|
140
141
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
|
|
142
|
+
return Promise.resolve();
|
|
141
143
|
}
|
|
142
144
|
|
|
143
145
|
txeGetDefaultAddress(): AztecAddress {
|
|
@@ -209,7 +211,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
209
211
|
await this.txeAddAccount(artifact, instance, secret);
|
|
210
212
|
} else {
|
|
211
213
|
await this.contractStore.addContractInstance(instance);
|
|
212
|
-
await this.contractStore.addContractArtifact(
|
|
214
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
213
215
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
214
216
|
}
|
|
215
217
|
}
|
|
@@ -219,7 +221,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
219
221
|
|
|
220
222
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
221
223
|
await this.contractStore.addContractInstance(instance);
|
|
222
|
-
await this.contractStore.addContractArtifact(
|
|
224
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
223
225
|
|
|
224
226
|
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
225
227
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
@@ -296,14 +298,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
296
298
|
throw new Error(message);
|
|
297
299
|
}
|
|
298
300
|
|
|
299
|
-
// When `from` is the zero address (
|
|
300
|
-
//
|
|
301
|
-
|
|
302
|
-
const effectiveScopes = from.isZero() ? undefined : [from];
|
|
301
|
+
// When `from` is the zero address (e.g. when deploying a new account contract), we return an
|
|
302
|
+
// empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
|
|
303
|
+
const effectiveScopes = from.isZero() ? [] : [from];
|
|
303
304
|
|
|
304
305
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
305
|
-
const utilityExecutor = async (call: FunctionCall) => {
|
|
306
|
-
await this.executeUtilityCall(call,
|
|
306
|
+
const utilityExecutor = async (call: FunctionCall, execScopes: AccessScopes) => {
|
|
307
|
+
await this.executeUtilityCall(call, execScopes);
|
|
307
308
|
};
|
|
308
309
|
|
|
309
310
|
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
@@ -313,6 +314,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
313
314
|
utilityExecutor,
|
|
314
315
|
blockHeader,
|
|
315
316
|
this.jobId,
|
|
317
|
+
effectiveScopes,
|
|
316
318
|
);
|
|
317
319
|
|
|
318
320
|
const blockNumber = await this.txeGetNextBlockNumber();
|
|
@@ -336,43 +338,37 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
336
338
|
|
|
337
339
|
const simulator = new WASMSimulator();
|
|
338
340
|
|
|
339
|
-
const privateExecutionOracle = new PrivateExecutionOracle(
|
|
341
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
340
342
|
argsHash,
|
|
341
343
|
txContext,
|
|
342
344
|
callContext,
|
|
343
|
-
|
|
344
|
-
blockHeader,
|
|
345
|
+
anchorBlockHeader: blockHeader,
|
|
345
346
|
utilityExecutor,
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
[],
|
|
350
|
-
HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
347
|
+
authWitnesses: Array.from(this.authwits.values()),
|
|
348
|
+
capsules: [],
|
|
349
|
+
executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
351
350
|
noteCache,
|
|
352
351
|
taggingIndexCache,
|
|
353
|
-
this.contractStore,
|
|
354
|
-
this.noteStore,
|
|
355
|
-
this.keyStore,
|
|
356
|
-
this.addressStore,
|
|
357
|
-
this.stateMachine.node,
|
|
358
|
-
this.senderTaggingStore,
|
|
359
|
-
this.recipientTaggingStore,
|
|
360
|
-
this.senderAddressBookStore,
|
|
361
|
-
this.capsuleStore,
|
|
362
|
-
this.privateEventStore,
|
|
363
|
-
this.stateMachine.contractSyncService,
|
|
364
|
-
this.jobId,
|
|
365
|
-
0,
|
|
366
|
-
minRevertibleSideEffectCounter,
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
* contract would perform, including setting senderForTags.
|
|
372
|
-
*/
|
|
373
|
-
from,
|
|
352
|
+
contractStore: this.contractStore,
|
|
353
|
+
noteStore: this.noteStore,
|
|
354
|
+
keyStore: this.keyStore,
|
|
355
|
+
addressStore: this.addressStore,
|
|
356
|
+
aztecNode: this.stateMachine.node,
|
|
357
|
+
senderTaggingStore: this.senderTaggingStore,
|
|
358
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
359
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
360
|
+
capsuleStore: this.capsuleStore,
|
|
361
|
+
privateEventStore: this.privateEventStore,
|
|
362
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
363
|
+
jobId: this.jobId,
|
|
364
|
+
totalPublicCalldataCount: 0,
|
|
365
|
+
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
366
|
+
scopes: effectiveScopes,
|
|
367
|
+
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
368
|
+
// contract would perform, including setting senderForTags.
|
|
369
|
+
senderForTags: from,
|
|
374
370
|
simulator,
|
|
375
|
-
);
|
|
371
|
+
});
|
|
376
372
|
|
|
377
373
|
// 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.
|
|
378
374
|
let result: PrivateExecutionResult;
|
|
@@ -411,7 +407,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
411
407
|
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
412
408
|
const { publicInputs } = await generateSimulatedProvingResult(
|
|
413
409
|
result,
|
|
414
|
-
this.contractStore,
|
|
410
|
+
(addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
|
|
411
|
+
this.stateMachine.node,
|
|
415
412
|
minRevertibleSideEffectCounter,
|
|
416
413
|
);
|
|
417
414
|
|
|
@@ -594,7 +591,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
594
591
|
constantData,
|
|
595
592
|
/*gasUsed=*/ new Gas(0, 0),
|
|
596
593
|
/*feePayer=*/ AztecAddress.zero(),
|
|
597
|
-
/*
|
|
594
|
+
/*expirationTimestamp=*/ 0n,
|
|
598
595
|
inputsForPublic,
|
|
599
596
|
undefined,
|
|
600
597
|
);
|
|
@@ -662,11 +659,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
662
659
|
return returnValues ?? [];
|
|
663
660
|
}
|
|
664
661
|
|
|
665
|
-
async
|
|
666
|
-
targetContractAddress: AztecAddress,
|
|
667
|
-
functionSelector: FunctionSelector,
|
|
668
|
-
args: Fr[],
|
|
669
|
-
) {
|
|
662
|
+
async txeExecuteUtilityFunction(targetContractAddress: AztecAddress, functionSelector: FunctionSelector, args: Fr[]) {
|
|
670
663
|
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
671
664
|
if (!artifact) {
|
|
672
665
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
@@ -677,28 +670,29 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
677
670
|
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
678
671
|
targetContractAddress,
|
|
679
672
|
functionSelector,
|
|
680
|
-
async call => {
|
|
681
|
-
await this.executeUtilityCall(call);
|
|
673
|
+
async (call, execScopes) => {
|
|
674
|
+
await this.executeUtilityCall(call, execScopes);
|
|
682
675
|
},
|
|
683
676
|
blockHeader,
|
|
684
677
|
this.jobId,
|
|
678
|
+
'ALL_SCOPES',
|
|
685
679
|
);
|
|
686
680
|
|
|
687
|
-
const call =
|
|
688
|
-
artifact.name,
|
|
689
|
-
targetContractAddress,
|
|
690
|
-
functionSelector,
|
|
691
|
-
FunctionType.UTILITY,
|
|
692
|
-
false,
|
|
693
|
-
false,
|
|
681
|
+
const call = FunctionCall.from({
|
|
682
|
+
name: artifact.name,
|
|
683
|
+
to: targetContractAddress,
|
|
684
|
+
selector: functionSelector,
|
|
685
|
+
type: FunctionType.UTILITY,
|
|
686
|
+
hideMsgSender: false,
|
|
687
|
+
isStatic: false,
|
|
694
688
|
args,
|
|
695
|
-
[],
|
|
696
|
-
);
|
|
689
|
+
returnTypes: [],
|
|
690
|
+
});
|
|
697
691
|
|
|
698
|
-
return this.executeUtilityCall(call);
|
|
692
|
+
return this.executeUtilityCall(call, 'ALL_SCOPES');
|
|
699
693
|
}
|
|
700
694
|
|
|
701
|
-
private async executeUtilityCall(call: FunctionCall, scopes
|
|
695
|
+
private async executeUtilityCall(call: FunctionCall, scopes: AccessScopes): Promise<Fr[]> {
|
|
702
696
|
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
703
697
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
704
698
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
@@ -711,24 +705,23 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
711
705
|
|
|
712
706
|
try {
|
|
713
707
|
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
714
|
-
const oracle = new UtilityExecutionOracle(
|
|
715
|
-
call.to,
|
|
716
|
-
[],
|
|
717
|
-
[],
|
|
708
|
+
const oracle = new UtilityExecutionOracle({
|
|
709
|
+
contractAddress: call.to,
|
|
710
|
+
authWitnesses: [],
|
|
711
|
+
capsules: [],
|
|
718
712
|
anchorBlockHeader,
|
|
719
|
-
this.contractStore,
|
|
720
|
-
this.noteStore,
|
|
721
|
-
this.keyStore,
|
|
722
|
-
this.addressStore,
|
|
723
|
-
this.stateMachine.node,
|
|
724
|
-
this.recipientTaggingStore,
|
|
725
|
-
this.senderAddressBookStore,
|
|
726
|
-
this.capsuleStore,
|
|
727
|
-
this.privateEventStore,
|
|
728
|
-
this.jobId,
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
);
|
|
713
|
+
contractStore: this.contractStore,
|
|
714
|
+
noteStore: this.noteStore,
|
|
715
|
+
keyStore: this.keyStore,
|
|
716
|
+
addressStore: this.addressStore,
|
|
717
|
+
aztecNode: this.stateMachine.node,
|
|
718
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
719
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
720
|
+
capsuleStore: this.capsuleStore,
|
|
721
|
+
privateEventStore: this.privateEventStore,
|
|
722
|
+
jobId: this.jobId,
|
|
723
|
+
scopes,
|
|
724
|
+
});
|
|
732
725
|
const acirExecutionResult = await new WASMSimulator()
|
|
733
726
|
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
734
727
|
.catch((err: Error) => {
|
|
@@ -744,10 +737,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
744
737
|
);
|
|
745
738
|
});
|
|
746
739
|
|
|
747
|
-
this.logger.verbose(`Utility
|
|
740
|
+
this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
|
|
748
741
|
return witnessMapToFields(acirExecutionResult.returnWitness);
|
|
749
742
|
} catch (err) {
|
|
750
|
-
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility
|
|
743
|
+
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
|
|
751
744
|
}
|
|
752
745
|
}
|
|
753
746
|
|
package/src/rpc_translator.ts
CHANGED
|
@@ -328,7 +328,7 @@ export class RPCTranslator {
|
|
|
328
328
|
|
|
329
329
|
// When the argument is a slice, noir automatically adds a length field to oracle call.
|
|
330
330
|
// When the argument is an array, we add the field length manually to the signature.
|
|
331
|
-
|
|
331
|
+
async utilityLog(
|
|
332
332
|
foreignLevel: ForeignCallSingle,
|
|
333
333
|
foreignMessage: ForeignCallArray,
|
|
334
334
|
_foreignLength: ForeignCallSingle,
|
|
@@ -340,7 +340,7 @@ export class RPCTranslator {
|
|
|
340
340
|
.join('');
|
|
341
341
|
const fields = fromArray(foreignFields);
|
|
342
342
|
|
|
343
|
-
this.handlerAsMisc().
|
|
343
|
+
await this.handlerAsMisc().utilityLog(level, message, fields);
|
|
344
344
|
|
|
345
345
|
return toForeignCallResult([]);
|
|
346
346
|
}
|
|
@@ -849,7 +849,7 @@ export class RPCTranslator {
|
|
|
849
849
|
|
|
850
850
|
// AVM opcodes
|
|
851
851
|
|
|
852
|
-
|
|
852
|
+
avmOpcodeEmitPublicLog(_foreignMessage: ForeignCallArray) {
|
|
853
853
|
// TODO(#8811): Implement
|
|
854
854
|
return toForeignCallResult([]);
|
|
855
855
|
}
|
|
@@ -1043,7 +1043,7 @@ export class RPCTranslator {
|
|
|
1043
1043
|
return toForeignCallResult([toArray(returnValues)]);
|
|
1044
1044
|
}
|
|
1045
1045
|
|
|
1046
|
-
async
|
|
1046
|
+
async txeExecuteUtilityFunction(
|
|
1047
1047
|
foreignTargetContractAddress: ForeignCallSingle,
|
|
1048
1048
|
foreignFunctionSelector: ForeignCallSingle,
|
|
1049
1049
|
foreignArgs: ForeignCallArray,
|
|
@@ -1052,7 +1052,7 @@ export class RPCTranslator {
|
|
|
1052
1052
|
const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
|
|
1053
1053
|
const args = fromArray(foreignArgs);
|
|
1054
1054
|
|
|
1055
|
-
const returnValues = await this.handlerAsTxe().
|
|
1055
|
+
const returnValues = await this.handlerAsTxe().txeExecuteUtilityFunction(
|
|
1056
1056
|
targetContractAddress,
|
|
1057
1057
|
functionSelector,
|
|
1058
1058
|
args,
|