@aztec/txe 0.0.1-commit.7d4e6cd → 0.0.1-commit.7ffbba4
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/constants.d.ts +1 -2
- package/dest/constants.d.ts.map +1 -1
- package/dest/constants.js +0 -1
- 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 +13 -13
- 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 -22
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +138 -61
- package/dest/rpc_translator.d.ts +86 -81
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +291 -175
- package/dest/state_machine/archiver.d.ts +20 -69
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +36 -178
- 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 +5 -5
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +35 -12
- 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 +11 -7
- 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 +11 -6
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +101 -26
- package/dest/util/encoding.d.ts +17 -17
- 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 +4 -4
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +18 -4
- package/dest/utils/tx_effect_creation.d.ts +2 -3
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +3 -6
- package/package.json +16 -16
- package/src/constants.ts +0 -1
- package/src/index.ts +89 -52
- package/src/oracle/interfaces.ts +32 -31
- package/src/oracle/txe_oracle_public_context.ts +16 -18
- package/src/oracle/txe_oracle_top_level_context.ts +173 -111
- package/src/rpc_translator.ts +313 -198
- package/src/state_machine/archiver.ts +37 -234
- package/src/state_machine/dummy_p2p_client.ts +40 -22
- package/src/state_machine/index.ts +49 -11
- package/src/state_machine/mock_epoch_cache.ts +11 -11
- package/src/state_machine/synchronizer.ts +2 -2
- package/src/txe_session.ts +115 -87
- package/src/util/txe_public_contract_data_source.ts +10 -36
- package/src/utils/block_creation.ts +19 -16
- package/src/utils/tx_effect_creation.ts +3 -11
- 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,
|
|
@@ -80,10 +82,9 @@ import {
|
|
|
80
82
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
81
83
|
import { ForkCheckpoint } from '@aztec/world-state';
|
|
82
84
|
|
|
83
|
-
import { DEFAULT_ADDRESS
|
|
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,
|
|
@@ -115,7 +116,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
115
116
|
this.logger.debug('Entering Top Level Context');
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
|
|
119
|
+
assertCompatibleOracleVersion(version: number): void {
|
|
119
120
|
if (version !== ORACLE_VERSION) {
|
|
120
121
|
throw new Error(
|
|
121
122
|
`Incompatible oracle version. TXE is using version '${ORACLE_VERSION}', but got a request for '${version}'.`,
|
|
@@ -125,38 +126,40 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
125
126
|
|
|
126
127
|
// This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
|
|
127
128
|
// setup.
|
|
128
|
-
|
|
129
|
+
getRandomField(): Fr {
|
|
129
130
|
return Fr.random();
|
|
130
131
|
}
|
|
131
132
|
|
|
132
133
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
133
|
-
|
|
134
|
+
log(level: number, message: string, fields: Fr[]): Promise<void> {
|
|
134
135
|
if (!LogLevels[level]) {
|
|
135
|
-
throw new Error(`Invalid
|
|
136
|
+
throw new Error(`Invalid log level: ${level}`);
|
|
136
137
|
}
|
|
137
138
|
const levelName = LogLevels[level];
|
|
138
139
|
|
|
139
140
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
|
|
141
|
+
return Promise.resolve();
|
|
140
142
|
}
|
|
141
143
|
|
|
142
|
-
|
|
144
|
+
getDefaultAddress(): AztecAddress {
|
|
143
145
|
return DEFAULT_ADDRESS;
|
|
144
146
|
}
|
|
145
147
|
|
|
146
|
-
async
|
|
148
|
+
async getNextBlockNumber(): Promise<BlockNumber> {
|
|
147
149
|
return BlockNumber((await this.getLastBlockNumber()) + 1);
|
|
148
150
|
}
|
|
149
151
|
|
|
150
|
-
|
|
152
|
+
getNextBlockTimestamp(): Promise<bigint> {
|
|
151
153
|
return Promise.resolve(this.nextBlockTimestamp);
|
|
152
154
|
}
|
|
153
155
|
|
|
154
|
-
async
|
|
156
|
+
async getLastBlockTimestamp() {
|
|
155
157
|
return (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.timestamp;
|
|
156
158
|
}
|
|
157
159
|
|
|
158
|
-
async
|
|
159
|
-
const
|
|
160
|
+
async getLastTxEffects() {
|
|
161
|
+
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
162
|
+
const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
|
|
160
163
|
|
|
161
164
|
if (block!.body.txEffects.length != 1) {
|
|
162
165
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
@@ -168,7 +171,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
168
171
|
return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
|
|
169
172
|
}
|
|
170
173
|
|
|
171
|
-
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) {
|
|
172
194
|
return (
|
|
173
195
|
await this.privateEventStore.getPrivateEvents(selector, {
|
|
174
196
|
contractAddress,
|
|
@@ -179,7 +201,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
179
201
|
).map(e => e.packedEvent);
|
|
180
202
|
}
|
|
181
203
|
|
|
182
|
-
async
|
|
204
|
+
async advanceBlocksBy(blocks: number) {
|
|
183
205
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
184
206
|
|
|
185
207
|
for (let i = 0; i < blocks; i++) {
|
|
@@ -187,12 +209,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
187
209
|
}
|
|
188
210
|
}
|
|
189
211
|
|
|
190
|
-
|
|
212
|
+
advanceTimestampBy(duration: UInt64) {
|
|
191
213
|
this.logger.debug(`time traveling ${duration} seconds`);
|
|
192
214
|
this.nextBlockTimestamp += duration;
|
|
193
215
|
}
|
|
194
216
|
|
|
195
|
-
async
|
|
217
|
+
async deploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
|
|
196
218
|
// Emit deployment nullifier
|
|
197
219
|
await this.mineBlock({
|
|
198
220
|
nullifiers: [
|
|
@@ -204,20 +226,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
204
226
|
});
|
|
205
227
|
|
|
206
228
|
if (!secret.equals(Fr.ZERO)) {
|
|
207
|
-
await this.
|
|
229
|
+
await this.addAccount(artifact, instance, secret);
|
|
208
230
|
} else {
|
|
209
231
|
await this.contractStore.addContractInstance(instance);
|
|
210
|
-
await this.contractStore.addContractArtifact(
|
|
232
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
211
233
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
212
234
|
}
|
|
213
235
|
}
|
|
214
236
|
|
|
215
|
-
async
|
|
237
|
+
async addAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
|
|
216
238
|
const partialAddress = await computePartialAddress(instance);
|
|
217
239
|
|
|
218
240
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
219
241
|
await this.contractStore.addContractInstance(instance);
|
|
220
|
-
await this.contractStore.addContractArtifact(
|
|
242
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
221
243
|
|
|
222
244
|
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
223
245
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
@@ -227,7 +249,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
227
249
|
return completeAddress;
|
|
228
250
|
}
|
|
229
251
|
|
|
230
|
-
async
|
|
252
|
+
async createAccount(secret: Fr) {
|
|
231
253
|
// This is a foot gun !
|
|
232
254
|
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
233
255
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
@@ -237,7 +259,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
237
259
|
return completeAddress;
|
|
238
260
|
}
|
|
239
261
|
|
|
240
|
-
async
|
|
262
|
+
async addAuthWitness(address: AztecAddress, messageHash: Fr) {
|
|
241
263
|
const account = await this.accountStore.getAccount(address);
|
|
242
264
|
const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
|
|
243
265
|
|
|
@@ -250,7 +272,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
250
272
|
}
|
|
251
273
|
|
|
252
274
|
async mineBlock(options: { nullifiers?: Fr[] } = {}) {
|
|
253
|
-
const blockNumber = await this.
|
|
275
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
254
276
|
|
|
255
277
|
const txEffect = TxEffect.empty();
|
|
256
278
|
txEffect.nullifiers = [getSingleTxBlockRequestHash(blockNumber), ...(options.nullifiers ?? [])];
|
|
@@ -274,13 +296,14 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
274
296
|
await this.stateMachine.handleL2Block(block);
|
|
275
297
|
}
|
|
276
298
|
|
|
277
|
-
async
|
|
299
|
+
async privateCallNewFlow(
|
|
278
300
|
from: AztecAddress,
|
|
279
301
|
targetContractAddress: AztecAddress = AztecAddress.zero(),
|
|
280
302
|
functionSelector: FunctionSelector = FunctionSelector.empty(),
|
|
281
303
|
args: Fr[],
|
|
282
304
|
argsHash: Fr = Fr.zero(),
|
|
283
305
|
isStaticCall: boolean = false,
|
|
306
|
+
jobId: string,
|
|
284
307
|
) {
|
|
285
308
|
this.logger.verbose(
|
|
286
309
|
`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
@@ -294,14 +317,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
294
317
|
throw new Error(message);
|
|
295
318
|
}
|
|
296
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
|
+
|
|
297
324
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
298
|
-
const utilityExecutor = async (call: FunctionCall) => {
|
|
299
|
-
await this.executeUtilityCall(call);
|
|
325
|
+
const utilityExecutor = async (call: FunctionCall, execScopes: AccessScopes) => {
|
|
326
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
300
327
|
};
|
|
301
328
|
|
|
302
|
-
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
|
+
);
|
|
303
338
|
|
|
304
|
-
const blockNumber = await this.
|
|
339
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
305
340
|
|
|
306
341
|
const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
|
|
307
342
|
|
|
@@ -311,51 +346,48 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
311
346
|
|
|
312
347
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
313
348
|
|
|
314
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
315
|
-
|
|
316
349
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
317
350
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
351
|
+
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
352
|
+
// Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
|
|
353
|
+
// marking all side effects as revertible.
|
|
354
|
+
const minRevertibleSideEffectCounter = 1;
|
|
355
|
+
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
318
356
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
319
357
|
|
|
320
358
|
const simulator = new WASMSimulator();
|
|
321
359
|
|
|
322
|
-
const privateExecutionOracle = new PrivateExecutionOracle(
|
|
360
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
323
361
|
argsHash,
|
|
324
362
|
txContext,
|
|
325
363
|
callContext,
|
|
326
|
-
|
|
327
|
-
blockHeader,
|
|
364
|
+
anchorBlockHeader: blockHeader,
|
|
328
365
|
utilityExecutor,
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
[],
|
|
333
|
-
HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
366
|
+
authWitnesses: Array.from(this.authwits.values()),
|
|
367
|
+
capsules: [],
|
|
368
|
+
executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
334
369
|
noteCache,
|
|
335
370
|
taggingIndexCache,
|
|
336
|
-
this.contractStore,
|
|
337
|
-
this.noteStore,
|
|
338
|
-
this.keyStore,
|
|
339
|
-
this.addressStore,
|
|
340
|
-
this.stateMachine.node,
|
|
341
|
-
this.
|
|
342
|
-
this.
|
|
343
|
-
this.
|
|
344
|
-
this.
|
|
345
|
-
this.
|
|
346
|
-
this.
|
|
347
|
-
|
|
348
|
-
0,
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
* contract would perform, including setting senderForTags.
|
|
355
|
-
*/
|
|
356
|
-
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,
|
|
357
389
|
simulator,
|
|
358
|
-
);
|
|
390
|
+
});
|
|
359
391
|
|
|
360
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.
|
|
361
393
|
let result: PrivateExecutionResult;
|
|
@@ -377,24 +409,27 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
377
409
|
);
|
|
378
410
|
const publicFunctionsCalldata = await Promise.all(
|
|
379
411
|
publicCallRequests.map(async r => {
|
|
380
|
-
const calldata = await privateExecutionOracle.
|
|
412
|
+
const calldata = await privateExecutionOracle.loadFromExecutionCache(r.calldataHash);
|
|
381
413
|
return new HashedValues(calldata, r.calldataHash);
|
|
382
414
|
}),
|
|
383
415
|
);
|
|
384
416
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
result = new PrivateExecutionResult(executionResult, Fr.ZERO, publicFunctionsCalldata);
|
|
417
|
+
noteCache.finish();
|
|
418
|
+
const nonceGenerator = noteCache.getNonceGenerator();
|
|
419
|
+
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
389
420
|
} catch (err) {
|
|
390
421
|
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
391
422
|
}
|
|
392
423
|
|
|
393
|
-
// According to the protocol rules,
|
|
394
|
-
//
|
|
395
|
-
//
|
|
396
|
-
const
|
|
397
|
-
|
|
424
|
+
// According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
|
|
425
|
+
// the nonce generator for the note hashes.
|
|
426
|
+
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
427
|
+
const { publicInputs } = await generateSimulatedProvingResult(
|
|
428
|
+
result,
|
|
429
|
+
(addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
|
|
430
|
+
this.stateMachine.node,
|
|
431
|
+
minRevertibleSideEffectCounter,
|
|
432
|
+
);
|
|
398
433
|
|
|
399
434
|
const globals = makeGlobalVariables();
|
|
400
435
|
globals.blockNumber = blockNumber;
|
|
@@ -405,7 +440,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
405
440
|
|
|
406
441
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
407
442
|
|
|
408
|
-
const
|
|
443
|
+
const bindings = this.logger.getBindings();
|
|
444
|
+
const contractsDB = new PublicContractsDB(
|
|
445
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
446
|
+
bindings,
|
|
447
|
+
);
|
|
409
448
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
410
449
|
const config = PublicSimulatorConfig.from({
|
|
411
450
|
skipFeeEnforcement: true,
|
|
@@ -418,8 +457,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
418
457
|
globals,
|
|
419
458
|
guardedMerkleTrees,
|
|
420
459
|
contractsDB,
|
|
421
|
-
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
|
|
460
|
+
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
|
|
422
461
|
new TestDateProvider(),
|
|
462
|
+
undefined,
|
|
463
|
+
createLogger('simulator:public-processor', bindings),
|
|
423
464
|
);
|
|
424
465
|
|
|
425
466
|
const tx = await Tx.create({
|
|
@@ -482,7 +523,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
482
523
|
return executionResult.returnValues ?? [];
|
|
483
524
|
}
|
|
484
525
|
|
|
485
|
-
async
|
|
526
|
+
async publicCallNewFlow(
|
|
486
527
|
from: AztecAddress,
|
|
487
528
|
targetContractAddress: AztecAddress,
|
|
488
529
|
calldata: Fr[],
|
|
@@ -492,7 +533,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
492
533
|
`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
493
534
|
);
|
|
494
535
|
|
|
495
|
-
const blockNumber = await this.
|
|
536
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
496
537
|
|
|
497
538
|
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
498
539
|
|
|
@@ -516,7 +557,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
516
557
|
|
|
517
558
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
518
559
|
|
|
519
|
-
const
|
|
560
|
+
const bindings2 = this.logger.getBindings();
|
|
561
|
+
const contractsDB = new PublicContractsDB(
|
|
562
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
563
|
+
bindings2,
|
|
564
|
+
);
|
|
520
565
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
521
566
|
const config = PublicSimulatorConfig.from({
|
|
522
567
|
skipFeeEnforcement: true,
|
|
@@ -525,8 +570,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
525
570
|
collectStatistics: false,
|
|
526
571
|
collectCallMetadata: true,
|
|
527
572
|
});
|
|
528
|
-
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
|
|
529
|
-
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
|
+
);
|
|
530
583
|
|
|
531
584
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
532
585
|
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
@@ -557,7 +610,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
557
610
|
constantData,
|
|
558
611
|
/*gasUsed=*/ new Gas(0, 0),
|
|
559
612
|
/*feePayer=*/ AztecAddress.zero(),
|
|
560
|
-
/*
|
|
613
|
+
/*expirationTimestamp=*/ 0n,
|
|
561
614
|
inputsForPublic,
|
|
562
615
|
undefined,
|
|
563
616
|
);
|
|
@@ -625,10 +678,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
625
678
|
return returnValues ?? [];
|
|
626
679
|
}
|
|
627
680
|
|
|
628
|
-
async
|
|
681
|
+
async executeUtilityFunction(
|
|
629
682
|
targetContractAddress: AztecAddress,
|
|
630
683
|
functionSelector: FunctionSelector,
|
|
631
684
|
args: Fr[],
|
|
685
|
+
jobId: string,
|
|
632
686
|
) {
|
|
633
687
|
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
634
688
|
if (!artifact) {
|
|
@@ -636,25 +690,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
636
690
|
}
|
|
637
691
|
|
|
638
692
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
639
|
-
await this.
|
|
640
|
-
|
|
641
|
-
});
|
|
642
|
-
|
|
643
|
-
const call = new FunctionCall(
|
|
644
|
-
artifact.name,
|
|
693
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
694
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
645
695
|
targetContractAddress,
|
|
646
696
|
functionSelector,
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
697
|
+
async (call, execScopes) => {
|
|
698
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
699
|
+
},
|
|
700
|
+
blockHeader,
|
|
701
|
+
jobId,
|
|
702
|
+
'ALL_SCOPES',
|
|
652
703
|
);
|
|
653
704
|
|
|
654
|
-
|
|
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);
|
|
655
717
|
}
|
|
656
718
|
|
|
657
|
-
private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
|
|
719
|
+
private async executeUtilityCall(call: FunctionCall, scopes: AccessScopes, jobId: string): Promise<Fr[]> {
|
|
658
720
|
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
659
721
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
660
722
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
@@ -667,23 +729,23 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
667
729
|
|
|
668
730
|
try {
|
|
669
731
|
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
670
|
-
const oracle = new UtilityExecutionOracle(
|
|
671
|
-
call.to,
|
|
672
|
-
[],
|
|
673
|
-
[],
|
|
732
|
+
const oracle = new UtilityExecutionOracle({
|
|
733
|
+
contractAddress: call.to,
|
|
734
|
+
authWitnesses: [],
|
|
735
|
+
capsules: [],
|
|
674
736
|
anchorBlockHeader,
|
|
675
|
-
this.contractStore,
|
|
676
|
-
this.noteStore,
|
|
677
|
-
this.keyStore,
|
|
678
|
-
this.addressStore,
|
|
679
|
-
this.stateMachine.node,
|
|
680
|
-
this.
|
|
681
|
-
this.
|
|
682
|
-
this.
|
|
683
|
-
this.
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
);
|
|
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
|
+
});
|
|
687
749
|
const acirExecutionResult = await new WASMSimulator()
|
|
688
750
|
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
689
751
|
.catch((err: Error) => {
|
|
@@ -699,10 +761,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
699
761
|
);
|
|
700
762
|
});
|
|
701
763
|
|
|
702
|
-
this.logger.verbose(`Utility
|
|
764
|
+
this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
|
|
703
765
|
return witnessMapToFields(acirExecutionResult.returnWitness);
|
|
704
766
|
} catch (err) {
|
|
705
|
-
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'));
|
|
706
768
|
}
|
|
707
769
|
}
|
|
708
770
|
|