@aztec/txe 0.0.1-commit.f295ac2 → 0.0.1-commit.f504929
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 +88 -54
- package/dest/oracle/interfaces.d.ts +29 -28
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.d.ts +15 -15
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +16 -16
- package/dest/oracle/txe_oracle_top_level_context.d.ts +22 -23
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +125 -54
- package/dest/rpc_translator.d.ts +87 -81
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +287 -170
- package/dest/state_machine/archiver.d.ts +2 -2
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +7 -6
- package/dest/state_machine/dummy_p2p_client.d.ts +16 -12
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +28 -16
- package/dest/state_machine/index.d.ts +7 -7
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +31 -17
- package/dest/state_machine/mock_epoch_cache.d.ts +8 -6
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +9 -6
- package/dest/state_machine/synchronizer.d.ts +3 -3
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/txe_session.d.ts +9 -6
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +86 -26
- 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/dest/utils/block_creation.d.ts +5 -5
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +7 -5
- package/package.json +15 -15
- package/src/index.ts +89 -52
- package/src/oracle/interfaces.ts +32 -31
- package/src/oracle/txe_oracle_public_context.ts +18 -20
- package/src/oracle/txe_oracle_top_level_context.ts +155 -102
- package/src/rpc_translator.ts +303 -177
- package/src/state_machine/archiver.ts +6 -8
- package/src/state_machine/dummy_p2p_client.ts +40 -22
- package/src/state_machine/index.ts +49 -19
- package/src/state_machine/mock_epoch_cache.ts +10 -11
- package/src/state_machine/synchronizer.ts +2 -2
- package/src/txe_session.ts +101 -85
- package/src/util/txe_public_contract_data_source.ts +10 -36
- package/src/utils/block_creation.ts +8 -6
- 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
|
@@ -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,
|
|
@@ -106,7 +107,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
106
107
|
private senderAddressBookStore: SenderAddressBookStore,
|
|
107
108
|
private capsuleStore: CapsuleStore,
|
|
108
109
|
private privateEventStore: PrivateEventStore,
|
|
109
|
-
private jobId: string,
|
|
110
110
|
private nextBlockTimestamp: bigint,
|
|
111
111
|
private version: Fr,
|
|
112
112
|
private chainId: Fr,
|
|
@@ -116,7 +116,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
116
116
|
this.logger.debug('Entering Top Level Context');
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
assertCompatibleOracleVersion(version: number): void {
|
|
120
120
|
if (version !== ORACLE_VERSION) {
|
|
121
121
|
throw new Error(
|
|
122
122
|
`Incompatible oracle version. TXE is using version '${ORACLE_VERSION}', but got a request for '${version}'.`,
|
|
@@ -126,37 +126,38 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
126
126
|
|
|
127
127
|
// This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
|
|
128
128
|
// setup.
|
|
129
|
-
|
|
129
|
+
getRandomField(): Fr {
|
|
130
130
|
return Fr.random();
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
134
|
-
|
|
134
|
+
log(level: number, message: string, fields: Fr[]): Promise<void> {
|
|
135
135
|
if (!LogLevels[level]) {
|
|
136
|
-
throw new Error(`Invalid
|
|
136
|
+
throw new Error(`Invalid log level: ${level}`);
|
|
137
137
|
}
|
|
138
138
|
const levelName = LogLevels[level];
|
|
139
139
|
|
|
140
140
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
|
|
141
|
+
return Promise.resolve();
|
|
141
142
|
}
|
|
142
143
|
|
|
143
|
-
|
|
144
|
+
getDefaultAddress(): AztecAddress {
|
|
144
145
|
return DEFAULT_ADDRESS;
|
|
145
146
|
}
|
|
146
147
|
|
|
147
|
-
async
|
|
148
|
+
async getNextBlockNumber(): Promise<BlockNumber> {
|
|
148
149
|
return BlockNumber((await this.getLastBlockNumber()) + 1);
|
|
149
150
|
}
|
|
150
151
|
|
|
151
|
-
|
|
152
|
+
getNextBlockTimestamp(): Promise<bigint> {
|
|
152
153
|
return Promise.resolve(this.nextBlockTimestamp);
|
|
153
154
|
}
|
|
154
155
|
|
|
155
|
-
async
|
|
156
|
+
async getLastBlockTimestamp() {
|
|
156
157
|
return (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.timestamp;
|
|
157
158
|
}
|
|
158
159
|
|
|
159
|
-
async
|
|
160
|
+
async getLastTxEffects() {
|
|
160
161
|
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
161
162
|
const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
|
|
162
163
|
|
|
@@ -170,7 +171,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
170
171
|
return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
|
|
171
172
|
}
|
|
172
173
|
|
|
173
|
-
async
|
|
174
|
+
async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
|
|
175
|
+
if (contractAddress.equals(DEFAULT_ADDRESS)) {
|
|
176
|
+
this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
181
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
182
|
+
contractAddress,
|
|
183
|
+
null,
|
|
184
|
+
async (call, execScopes) => {
|
|
185
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
186
|
+
},
|
|
187
|
+
blockHeader,
|
|
188
|
+
jobId,
|
|
189
|
+
[scope],
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
|
|
174
194
|
return (
|
|
175
195
|
await this.privateEventStore.getPrivateEvents(selector, {
|
|
176
196
|
contractAddress,
|
|
@@ -181,7 +201,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
181
201
|
).map(e => e.packedEvent);
|
|
182
202
|
}
|
|
183
203
|
|
|
184
|
-
async
|
|
204
|
+
async advanceBlocksBy(blocks: number) {
|
|
185
205
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
186
206
|
|
|
187
207
|
for (let i = 0; i < blocks; i++) {
|
|
@@ -189,12 +209,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
189
209
|
}
|
|
190
210
|
}
|
|
191
211
|
|
|
192
|
-
|
|
212
|
+
advanceTimestampBy(duration: UInt64) {
|
|
193
213
|
this.logger.debug(`time traveling ${duration} seconds`);
|
|
194
214
|
this.nextBlockTimestamp += duration;
|
|
195
215
|
}
|
|
196
216
|
|
|
197
|
-
async
|
|
217
|
+
async deploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
|
|
198
218
|
// Emit deployment nullifier
|
|
199
219
|
await this.mineBlock({
|
|
200
220
|
nullifiers: [
|
|
@@ -206,20 +226,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
206
226
|
});
|
|
207
227
|
|
|
208
228
|
if (!secret.equals(Fr.ZERO)) {
|
|
209
|
-
await this.
|
|
229
|
+
await this.addAccount(artifact, instance, secret);
|
|
210
230
|
} else {
|
|
211
231
|
await this.contractStore.addContractInstance(instance);
|
|
212
|
-
await this.contractStore.addContractArtifact(
|
|
232
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
213
233
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
214
234
|
}
|
|
215
235
|
}
|
|
216
236
|
|
|
217
|
-
async
|
|
237
|
+
async addAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
|
|
218
238
|
const partialAddress = await computePartialAddress(instance);
|
|
219
239
|
|
|
220
240
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
221
241
|
await this.contractStore.addContractInstance(instance);
|
|
222
|
-
await this.contractStore.addContractArtifact(
|
|
242
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
223
243
|
|
|
224
244
|
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
225
245
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
@@ -229,7 +249,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
229
249
|
return completeAddress;
|
|
230
250
|
}
|
|
231
251
|
|
|
232
|
-
async
|
|
252
|
+
async createAccount(secret: Fr) {
|
|
233
253
|
// This is a foot gun !
|
|
234
254
|
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
235
255
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
@@ -239,7 +259,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
239
259
|
return completeAddress;
|
|
240
260
|
}
|
|
241
261
|
|
|
242
|
-
async
|
|
262
|
+
async addAuthWitness(address: AztecAddress, messageHash: Fr) {
|
|
243
263
|
const account = await this.accountStore.getAccount(address);
|
|
244
264
|
const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
|
|
245
265
|
|
|
@@ -252,7 +272,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
252
272
|
}
|
|
253
273
|
|
|
254
274
|
async mineBlock(options: { nullifiers?: Fr[] } = {}) {
|
|
255
|
-
const blockNumber = await this.
|
|
275
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
256
276
|
|
|
257
277
|
const txEffect = TxEffect.empty();
|
|
258
278
|
txEffect.nullifiers = [getSingleTxBlockRequestHash(blockNumber), ...(options.nullifiers ?? [])];
|
|
@@ -276,13 +296,14 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
276
296
|
await this.stateMachine.handleL2Block(block);
|
|
277
297
|
}
|
|
278
298
|
|
|
279
|
-
async
|
|
299
|
+
async privateCallNewFlow(
|
|
280
300
|
from: AztecAddress,
|
|
281
301
|
targetContractAddress: AztecAddress = AztecAddress.zero(),
|
|
282
302
|
functionSelector: FunctionSelector = FunctionSelector.empty(),
|
|
283
303
|
args: Fr[],
|
|
284
304
|
argsHash: Fr = Fr.zero(),
|
|
285
305
|
isStaticCall: boolean = false,
|
|
306
|
+
jobId: string,
|
|
286
307
|
) {
|
|
287
308
|
this.logger.verbose(
|
|
288
309
|
`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
@@ -296,14 +317,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
296
317
|
throw new Error(message);
|
|
297
318
|
}
|
|
298
319
|
|
|
320
|
+
// When `from` is the zero address (e.g. when deploying a new account contract), we return an
|
|
321
|
+
// empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
|
|
322
|
+
const effectiveScopes = from.isZero() ? [] : [from];
|
|
323
|
+
|
|
299
324
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
300
|
-
const utilityExecutor = async (call: FunctionCall) => {
|
|
301
|
-
await this.executeUtilityCall(call);
|
|
325
|
+
const utilityExecutor = async (call: FunctionCall, execScopes: AccessScopes) => {
|
|
326
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
302
327
|
};
|
|
303
328
|
|
|
304
|
-
await this.
|
|
329
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
330
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
331
|
+
targetContractAddress,
|
|
332
|
+
functionSelector,
|
|
333
|
+
utilityExecutor,
|
|
334
|
+
blockHeader,
|
|
335
|
+
jobId,
|
|
336
|
+
effectiveScopes,
|
|
337
|
+
);
|
|
305
338
|
|
|
306
|
-
const blockNumber = await this.
|
|
339
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
307
340
|
|
|
308
341
|
const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
|
|
309
342
|
|
|
@@ -313,8 +346,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
313
346
|
|
|
314
347
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
315
348
|
|
|
316
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
317
|
-
|
|
318
349
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
319
350
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
320
351
|
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
@@ -326,43 +357,37 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
326
357
|
|
|
327
358
|
const simulator = new WASMSimulator();
|
|
328
359
|
|
|
329
|
-
const privateExecutionOracle = new PrivateExecutionOracle(
|
|
360
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
330
361
|
argsHash,
|
|
331
362
|
txContext,
|
|
332
363
|
callContext,
|
|
333
|
-
|
|
334
|
-
blockHeader,
|
|
364
|
+
anchorBlockHeader: blockHeader,
|
|
335
365
|
utilityExecutor,
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
[],
|
|
340
|
-
HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
366
|
+
authWitnesses: Array.from(this.authwits.values()),
|
|
367
|
+
capsules: [],
|
|
368
|
+
executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
341
369
|
noteCache,
|
|
342
370
|
taggingIndexCache,
|
|
343
|
-
this.contractStore,
|
|
344
|
-
this.noteStore,
|
|
345
|
-
this.keyStore,
|
|
346
|
-
this.addressStore,
|
|
347
|
-
this.stateMachine.node,
|
|
348
|
-
this.
|
|
349
|
-
this.
|
|
350
|
-
this.
|
|
351
|
-
this.
|
|
352
|
-
this.
|
|
353
|
-
this.
|
|
354
|
-
|
|
355
|
-
0,
|
|
356
|
-
minRevertibleSideEffectCounter,
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
* contract would perform, including setting senderForTags.
|
|
362
|
-
*/
|
|
363
|
-
from,
|
|
371
|
+
contractStore: this.contractStore,
|
|
372
|
+
noteStore: this.noteStore,
|
|
373
|
+
keyStore: this.keyStore,
|
|
374
|
+
addressStore: this.addressStore,
|
|
375
|
+
aztecNode: this.stateMachine.node,
|
|
376
|
+
senderTaggingStore: this.senderTaggingStore,
|
|
377
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
378
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
379
|
+
capsuleStore: this.capsuleStore,
|
|
380
|
+
privateEventStore: this.privateEventStore,
|
|
381
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
382
|
+
jobId,
|
|
383
|
+
totalPublicCalldataCount: 0,
|
|
384
|
+
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
385
|
+
scopes: effectiveScopes,
|
|
386
|
+
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
387
|
+
// contract would perform, including setting senderForTags.
|
|
388
|
+
senderForTags: from,
|
|
364
389
|
simulator,
|
|
365
|
-
);
|
|
390
|
+
});
|
|
366
391
|
|
|
367
392
|
// 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.
|
|
368
393
|
let result: PrivateExecutionResult;
|
|
@@ -384,7 +409,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
384
409
|
);
|
|
385
410
|
const publicFunctionsCalldata = await Promise.all(
|
|
386
411
|
publicCallRequests.map(async r => {
|
|
387
|
-
const calldata = await privateExecutionOracle.
|
|
412
|
+
const calldata = await privateExecutionOracle.loadFromExecutionCache(r.calldataHash);
|
|
388
413
|
return new HashedValues(calldata, r.calldataHash);
|
|
389
414
|
}),
|
|
390
415
|
);
|
|
@@ -401,7 +426,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
401
426
|
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
402
427
|
const { publicInputs } = await generateSimulatedProvingResult(
|
|
403
428
|
result,
|
|
404
|
-
this.contractStore,
|
|
429
|
+
(addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
|
|
430
|
+
this.stateMachine.node,
|
|
405
431
|
minRevertibleSideEffectCounter,
|
|
406
432
|
);
|
|
407
433
|
|
|
@@ -414,7 +440,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
414
440
|
|
|
415
441
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
416
442
|
|
|
417
|
-
const
|
|
443
|
+
const bindings = this.logger.getBindings();
|
|
444
|
+
const contractsDB = new PublicContractsDB(
|
|
445
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
446
|
+
bindings,
|
|
447
|
+
);
|
|
418
448
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
419
449
|
const config = PublicSimulatorConfig.from({
|
|
420
450
|
skipFeeEnforcement: true,
|
|
@@ -427,8 +457,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
427
457
|
globals,
|
|
428
458
|
guardedMerkleTrees,
|
|
429
459
|
contractsDB,
|
|
430
|
-
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
|
|
460
|
+
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
|
|
431
461
|
new TestDateProvider(),
|
|
462
|
+
undefined,
|
|
463
|
+
createLogger('simulator:public-processor', bindings),
|
|
432
464
|
);
|
|
433
465
|
|
|
434
466
|
const tx = await Tx.create({
|
|
@@ -491,7 +523,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
491
523
|
return executionResult.returnValues ?? [];
|
|
492
524
|
}
|
|
493
525
|
|
|
494
|
-
async
|
|
526
|
+
async publicCallNewFlow(
|
|
495
527
|
from: AztecAddress,
|
|
496
528
|
targetContractAddress: AztecAddress,
|
|
497
529
|
calldata: Fr[],
|
|
@@ -501,7 +533,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
501
533
|
`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
502
534
|
);
|
|
503
535
|
|
|
504
|
-
const blockNumber = await this.
|
|
536
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
505
537
|
|
|
506
538
|
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
507
539
|
|
|
@@ -525,7 +557,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
525
557
|
|
|
526
558
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
527
559
|
|
|
528
|
-
const
|
|
560
|
+
const bindings2 = this.logger.getBindings();
|
|
561
|
+
const contractsDB = new PublicContractsDB(
|
|
562
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
563
|
+
bindings2,
|
|
564
|
+
);
|
|
529
565
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
530
566
|
const config = PublicSimulatorConfig.from({
|
|
531
567
|
skipFeeEnforcement: true,
|
|
@@ -534,8 +570,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
534
570
|
collectStatistics: false,
|
|
535
571
|
collectCallMetadata: true,
|
|
536
572
|
});
|
|
537
|
-
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
|
|
538
|
-
const processor = new PublicProcessor(
|
|
573
|
+
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
|
|
574
|
+
const processor = new PublicProcessor(
|
|
575
|
+
globals,
|
|
576
|
+
guardedMerkleTrees,
|
|
577
|
+
contractsDB,
|
|
578
|
+
simulator,
|
|
579
|
+
new TestDateProvider(),
|
|
580
|
+
undefined,
|
|
581
|
+
createLogger('simulator:public-processor', bindings2),
|
|
582
|
+
);
|
|
539
583
|
|
|
540
584
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
541
585
|
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
@@ -566,7 +610,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
566
610
|
constantData,
|
|
567
611
|
/*gasUsed=*/ new Gas(0, 0),
|
|
568
612
|
/*feePayer=*/ AztecAddress.zero(),
|
|
569
|
-
/*
|
|
613
|
+
/*expirationTimestamp=*/ 0n,
|
|
570
614
|
inputsForPublic,
|
|
571
615
|
undefined,
|
|
572
616
|
);
|
|
@@ -634,10 +678,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
634
678
|
return returnValues ?? [];
|
|
635
679
|
}
|
|
636
680
|
|
|
637
|
-
async
|
|
681
|
+
async executeUtilityFunction(
|
|
638
682
|
targetContractAddress: AztecAddress,
|
|
639
683
|
functionSelector: FunctionSelector,
|
|
640
684
|
args: Fr[],
|
|
685
|
+
jobId: string,
|
|
641
686
|
) {
|
|
642
687
|
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
643
688
|
if (!artifact) {
|
|
@@ -645,25 +690,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
645
690
|
}
|
|
646
691
|
|
|
647
692
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
648
|
-
await this.
|
|
649
|
-
|
|
650
|
-
});
|
|
651
|
-
|
|
652
|
-
const call = new FunctionCall(
|
|
653
|
-
artifact.name,
|
|
693
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
694
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
654
695
|
targetContractAddress,
|
|
655
696
|
functionSelector,
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
697
|
+
async (call, execScopes) => {
|
|
698
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
699
|
+
},
|
|
700
|
+
blockHeader,
|
|
701
|
+
jobId,
|
|
702
|
+
'ALL_SCOPES',
|
|
661
703
|
);
|
|
662
704
|
|
|
663
|
-
|
|
705
|
+
const call = FunctionCall.from({
|
|
706
|
+
name: artifact.name,
|
|
707
|
+
to: targetContractAddress,
|
|
708
|
+
selector: functionSelector,
|
|
709
|
+
type: FunctionType.UTILITY,
|
|
710
|
+
hideMsgSender: false,
|
|
711
|
+
isStatic: false,
|
|
712
|
+
args,
|
|
713
|
+
returnTypes: [],
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
return this.executeUtilityCall(call, 'ALL_SCOPES', jobId);
|
|
664
717
|
}
|
|
665
718
|
|
|
666
|
-
private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
|
|
719
|
+
private async executeUtilityCall(call: FunctionCall, scopes: AccessScopes, jobId: string): Promise<Fr[]> {
|
|
667
720
|
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
668
721
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
669
722
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
@@ -676,23 +729,23 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
676
729
|
|
|
677
730
|
try {
|
|
678
731
|
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
679
|
-
const oracle = new UtilityExecutionOracle(
|
|
680
|
-
call.to,
|
|
681
|
-
[],
|
|
682
|
-
[],
|
|
732
|
+
const oracle = new UtilityExecutionOracle({
|
|
733
|
+
contractAddress: call.to,
|
|
734
|
+
authWitnesses: [],
|
|
735
|
+
capsules: [],
|
|
683
736
|
anchorBlockHeader,
|
|
684
|
-
this.contractStore,
|
|
685
|
-
this.noteStore,
|
|
686
|
-
this.keyStore,
|
|
687
|
-
this.addressStore,
|
|
688
|
-
this.stateMachine.node,
|
|
689
|
-
this.
|
|
690
|
-
this.
|
|
691
|
-
this.
|
|
692
|
-
this.
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
);
|
|
737
|
+
contractStore: this.contractStore,
|
|
738
|
+
noteStore: this.noteStore,
|
|
739
|
+
keyStore: this.keyStore,
|
|
740
|
+
addressStore: this.addressStore,
|
|
741
|
+
aztecNode: this.stateMachine.node,
|
|
742
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
743
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
744
|
+
capsuleStore: this.capsuleStore,
|
|
745
|
+
privateEventStore: this.privateEventStore,
|
|
746
|
+
jobId,
|
|
747
|
+
scopes,
|
|
748
|
+
});
|
|
696
749
|
const acirExecutionResult = await new WASMSimulator()
|
|
697
750
|
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
698
751
|
.catch((err: Error) => {
|
|
@@ -708,10 +761,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
708
761
|
);
|
|
709
762
|
});
|
|
710
763
|
|
|
711
|
-
this.logger.verbose(`Utility
|
|
764
|
+
this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
|
|
712
765
|
return witnessMapToFields(acirExecutionResult.returnWitness);
|
|
713
766
|
} catch (err) {
|
|
714
|
-
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility
|
|
767
|
+
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
|
|
715
768
|
}
|
|
716
769
|
}
|
|
717
770
|
|