@aztec/txe 0.0.1-commit.6d3c34e → 0.0.1-commit.6d63667d
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/oracle/interfaces.d.ts +3 -3
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.d.ts +3 -3
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +6 -6
- package/dest/oracle/txe_oracle_top_level_context.d.ts +3 -2
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +40 -25
- package/dest/rpc_translator.d.ts +17 -11
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +73 -48
- 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/index.d.ts +5 -5
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +34 -11
- package/dest/state_machine/mock_epoch_cache.d.ts +6 -6
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +7 -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 +5 -3
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +35 -16
- package/dest/util/encoding.d.ts +17 -17
- 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/oracle/interfaces.ts +2 -2
- package/src/oracle/txe_oracle_public_context.ts +6 -8
- package/src/oracle/txe_oracle_top_level_context.ts +76 -31
- package/src/rpc_translator.ts +76 -50
- package/src/state_machine/archiver.ts +37 -234
- package/src/state_machine/index.ts +48 -11
- package/src/state_machine/mock_epoch_cache.ts +6 -11
- package/src/state_machine/synchronizer.ts +2 -2
- package/src/txe_session.ts +44 -25
- package/src/utils/block_creation.ts +19 -16
- package/src/utils/tx_effect_creation.ts +3 -11
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
2
|
import { computeNoteHashNonce, computeUniqueNoteHash, siloNoteHash } from '@aztec/stdlib/hash';
|
|
3
3
|
import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
4
|
-
export async function makeTxEffect(noteCache,
|
|
4
|
+
export async function makeTxEffect(noteCache, txBlockNumber) {
|
|
5
5
|
const txEffect = TxEffect.empty();
|
|
6
|
-
|
|
7
|
-
const nonceGenerator =
|
|
6
|
+
noteCache.finish();
|
|
7
|
+
const nonceGenerator = noteCache.getNonceGenerator();
|
|
8
8
|
txEffect.noteHashes = await Promise.all(noteCache.getAllNotes().map(async (pendingNote, i)=>computeUniqueNoteHash(await computeNoteHashNonce(nonceGenerator, i), await siloNoteHash(pendingNote.note.contractAddress, pendingNote.noteHashForConsumption))));
|
|
9
9
|
// Nullifiers are already siloed
|
|
10
10
|
txEffect.nullifiers = noteCache.getAllNullifiers();
|
|
11
|
-
if (usedProtocolNullifierForNonces) {
|
|
12
|
-
txEffect.nullifiers.unshift(protocolNullifier);
|
|
13
|
-
}
|
|
14
11
|
txEffect.txHash = new TxHash(new Fr(txBlockNumber));
|
|
15
12
|
return txEffect;
|
|
16
13
|
}
|
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.6d63667d",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dest/index.js",
|
|
6
6
|
"bin": "./dest/bin/index.js",
|
|
@@ -61,27 +61,27 @@
|
|
|
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.6d63667d",
|
|
65
|
+
"@aztec/archiver": "0.0.1-commit.6d63667d",
|
|
66
|
+
"@aztec/aztec-node": "0.0.1-commit.6d63667d",
|
|
67
|
+
"@aztec/aztec.js": "0.0.1-commit.6d63667d",
|
|
68
|
+
"@aztec/bb-prover": "0.0.1-commit.6d63667d",
|
|
69
|
+
"@aztec/constants": "0.0.1-commit.6d63667d",
|
|
70
|
+
"@aztec/foundation": "0.0.1-commit.6d63667d",
|
|
71
|
+
"@aztec/key-store": "0.0.1-commit.6d63667d",
|
|
72
|
+
"@aztec/kv-store": "0.0.1-commit.6d63667d",
|
|
73
|
+
"@aztec/protocol-contracts": "0.0.1-commit.6d63667d",
|
|
74
|
+
"@aztec/pxe": "0.0.1-commit.6d63667d",
|
|
75
|
+
"@aztec/simulator": "0.0.1-commit.6d63667d",
|
|
76
|
+
"@aztec/stdlib": "0.0.1-commit.6d63667d",
|
|
77
|
+
"@aztec/world-state": "0.0.1-commit.6d63667d",
|
|
78
78
|
"zod": "^3.23.8"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
81
|
"@jest/globals": "^30.0.0",
|
|
82
82
|
"@types/jest": "^30.0.0",
|
|
83
83
|
"@types/node": "^22.15.17",
|
|
84
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
84
|
+
"@typescript/native-preview": "7.0.0-dev.20260113.1",
|
|
85
85
|
"jest": "^30.0.0",
|
|
86
86
|
"jest-mock-extended": "^4.0.0",
|
|
87
87
|
"ts-node": "^10.9.1",
|
package/src/constants.ts
CHANGED
package/src/oracle/interfaces.ts
CHANGED
|
@@ -33,9 +33,9 @@ export interface IAvmExecutionOracle {
|
|
|
33
33
|
avmOpcodeVersion(): Promise<Fr>;
|
|
34
34
|
avmOpcodeEmitNullifier(nullifier: Fr): Promise<void>;
|
|
35
35
|
avmOpcodeEmitNoteHash(noteHash: Fr): Promise<void>;
|
|
36
|
-
avmOpcodeNullifierExists(
|
|
36
|
+
avmOpcodeNullifierExists(siloedNullifier: Fr): Promise<boolean>;
|
|
37
37
|
avmOpcodeStorageWrite(slot: Fr, value: Fr): Promise<void>;
|
|
38
|
-
avmOpcodeStorageRead(slot: Fr): Promise<Fr>;
|
|
38
|
+
avmOpcodeStorageRead(slot: Fr, contractAddress: AztecAddress): Promise<Fr>;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
@@ -78,13 +78,11 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
|
|
|
78
78
|
this.transientUniqueNoteHashes.push(siloedNoteHash);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
async avmOpcodeNullifierExists(
|
|
82
|
-
const nullifier = await siloNullifier(targetAddress, innerNullifier!);
|
|
83
|
-
|
|
81
|
+
async avmOpcodeNullifierExists(siloedNullifier: Fr): Promise<boolean> {
|
|
84
82
|
const treeIndex = (
|
|
85
|
-
await this.forkedWorldTrees.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [
|
|
83
|
+
await this.forkedWorldTrees.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [siloedNullifier.toBuffer()])
|
|
86
84
|
)[0];
|
|
87
|
-
const transientIndex = this.transientSiloedNullifiers.find(n => n.equals(
|
|
85
|
+
const transientIndex = this.transientSiloedNullifiers.find(n => n.equals(siloedNullifier));
|
|
88
86
|
|
|
89
87
|
return treeIndex !== undefined || transientIndex !== undefined;
|
|
90
88
|
}
|
|
@@ -101,8 +99,8 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
|
|
|
101
99
|
]);
|
|
102
100
|
}
|
|
103
101
|
|
|
104
|
-
async avmOpcodeStorageRead(slot: Fr): Promise<Fr> {
|
|
105
|
-
const leafSlot = await computePublicDataTreeLeafSlot(
|
|
102
|
+
async avmOpcodeStorageRead(slot: Fr, contractAddress: AztecAddress): Promise<Fr> {
|
|
103
|
+
const leafSlot = await computePublicDataTreeLeafSlot(contractAddress, slot);
|
|
106
104
|
|
|
107
105
|
const lowLeafResult = await this.forkedWorldTrees.getPreviousValueIndex(
|
|
108
106
|
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
@@ -119,7 +117,7 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
|
|
|
119
117
|
)) as PublicDataTreeLeafPreimage
|
|
120
118
|
).leaf.value;
|
|
121
119
|
|
|
122
|
-
this.logger.debug('AVM storage read', { slot, value });
|
|
120
|
+
this.logger.debug('AVM storage read', { slot, contractAddress, value });
|
|
123
121
|
|
|
124
122
|
return value;
|
|
125
123
|
}
|
|
@@ -80,7 +80,7 @@ import {
|
|
|
80
80
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
81
81
|
import { ForkCheckpoint } from '@aztec/world-state';
|
|
82
82
|
|
|
83
|
-
import { DEFAULT_ADDRESS
|
|
83
|
+
import { DEFAULT_ADDRESS } from '../constants.js';
|
|
84
84
|
import type { TXEStateMachine } from '../state_machine/index.js';
|
|
85
85
|
import type { TXEAccountStore } from '../util/txe_account_store.js';
|
|
86
86
|
import type { TXEContractStore } from '../util/txe_contract_store.js';
|
|
@@ -106,6 +106,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
106
106
|
private senderAddressBookStore: SenderAddressBookStore,
|
|
107
107
|
private capsuleStore: CapsuleStore,
|
|
108
108
|
private privateEventStore: PrivateEventStore,
|
|
109
|
+
private jobId: string,
|
|
109
110
|
private nextBlockTimestamp: bigint,
|
|
110
111
|
private version: Fr,
|
|
111
112
|
private chainId: Fr,
|
|
@@ -156,7 +157,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
async txeGetLastTxEffects() {
|
|
159
|
-
const
|
|
160
|
+
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
161
|
+
const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
|
|
160
162
|
|
|
161
163
|
if (block!.body.txEffects.length != 1) {
|
|
162
164
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
@@ -294,12 +296,24 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
294
296
|
throw new Error(message);
|
|
295
297
|
}
|
|
296
298
|
|
|
299
|
+
// When `from` is the zero address (used when creating a new contract account for example),
|
|
300
|
+
// we disable scope filtering by setting effectiveScopes to undefined. This allows these operations
|
|
301
|
+
// to proceed without requiring keys registered for the zero address.
|
|
302
|
+
const effectiveScopes = from.isZero() ? undefined : [from];
|
|
303
|
+
|
|
297
304
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
298
305
|
const utilityExecutor = async (call: FunctionCall) => {
|
|
299
|
-
await this.executeUtilityCall(call);
|
|
306
|
+
await this.executeUtilityCall(call, effectiveScopes);
|
|
300
307
|
};
|
|
301
308
|
|
|
302
|
-
await this.
|
|
309
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
310
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
311
|
+
targetContractAddress,
|
|
312
|
+
functionSelector,
|
|
313
|
+
utilityExecutor,
|
|
314
|
+
blockHeader,
|
|
315
|
+
this.jobId,
|
|
316
|
+
);
|
|
303
317
|
|
|
304
318
|
const blockNumber = await this.txeGetNextBlockNumber();
|
|
305
319
|
|
|
@@ -311,10 +325,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
311
325
|
|
|
312
326
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
313
327
|
|
|
314
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
315
|
-
|
|
316
328
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
317
329
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
330
|
+
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
331
|
+
// Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
|
|
332
|
+
// marking all side effects as revertible.
|
|
333
|
+
const minRevertibleSideEffectCounter = 1;
|
|
334
|
+
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
318
335
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
319
336
|
|
|
320
337
|
const simulator = new WASMSimulator();
|
|
@@ -338,17 +355,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
338
355
|
this.keyStore,
|
|
339
356
|
this.addressStore,
|
|
340
357
|
this.stateMachine.node,
|
|
341
|
-
this.stateMachine.anchorBlockStore,
|
|
342
358
|
this.senderTaggingStore,
|
|
343
359
|
this.recipientTaggingStore,
|
|
344
360
|
this.senderAddressBookStore,
|
|
345
361
|
this.capsuleStore,
|
|
346
362
|
this.privateEventStore,
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
363
|
+
this.stateMachine.contractSyncService,
|
|
364
|
+
this.jobId,
|
|
365
|
+
0, // totalPublicArgsCount
|
|
366
|
+
minRevertibleSideEffectCounter, // (start) sideEffectCounter
|
|
350
367
|
undefined, // log
|
|
351
|
-
|
|
368
|
+
effectiveScopes, // scopes
|
|
352
369
|
/**
|
|
353
370
|
* In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
354
371
|
* contract would perform, including setting senderForTags.
|
|
@@ -382,19 +399,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
382
399
|
}),
|
|
383
400
|
);
|
|
384
401
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
result = new PrivateExecutionResult(executionResult, Fr.ZERO, publicFunctionsCalldata);
|
|
402
|
+
noteCache.finish();
|
|
403
|
+
const nonceGenerator = noteCache.getNonceGenerator();
|
|
404
|
+
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
389
405
|
} catch (err) {
|
|
390
406
|
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
391
407
|
}
|
|
392
408
|
|
|
393
|
-
// According to the protocol rules,
|
|
394
|
-
//
|
|
395
|
-
//
|
|
396
|
-
const
|
|
397
|
-
|
|
409
|
+
// According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
|
|
410
|
+
// the nonce generator for the note hashes.
|
|
411
|
+
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
412
|
+
const { publicInputs } = await generateSimulatedProvingResult(
|
|
413
|
+
result,
|
|
414
|
+
this.contractStore,
|
|
415
|
+
minRevertibleSideEffectCounter,
|
|
416
|
+
);
|
|
398
417
|
|
|
399
418
|
const globals = makeGlobalVariables();
|
|
400
419
|
globals.blockNumber = blockNumber;
|
|
@@ -405,7 +424,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
405
424
|
|
|
406
425
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
407
426
|
|
|
408
|
-
const
|
|
427
|
+
const bindings = this.logger.getBindings();
|
|
428
|
+
const contractsDB = new PublicContractsDB(
|
|
429
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
430
|
+
bindings,
|
|
431
|
+
);
|
|
409
432
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
410
433
|
const config = PublicSimulatorConfig.from({
|
|
411
434
|
skipFeeEnforcement: true,
|
|
@@ -418,8 +441,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
418
441
|
globals,
|
|
419
442
|
guardedMerkleTrees,
|
|
420
443
|
contractsDB,
|
|
421
|
-
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
|
|
444
|
+
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
|
|
422
445
|
new TestDateProvider(),
|
|
446
|
+
undefined,
|
|
447
|
+
createLogger('simulator:public-processor', bindings),
|
|
423
448
|
);
|
|
424
449
|
|
|
425
450
|
const tx = await Tx.create({
|
|
@@ -516,7 +541,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
516
541
|
|
|
517
542
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
518
543
|
|
|
519
|
-
const
|
|
544
|
+
const bindings2 = this.logger.getBindings();
|
|
545
|
+
const contractsDB = new PublicContractsDB(
|
|
546
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
547
|
+
bindings2,
|
|
548
|
+
);
|
|
520
549
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
521
550
|
const config = PublicSimulatorConfig.from({
|
|
522
551
|
skipFeeEnforcement: true,
|
|
@@ -525,8 +554,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
525
554
|
collectStatistics: false,
|
|
526
555
|
collectCallMetadata: true,
|
|
527
556
|
});
|
|
528
|
-
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
|
|
529
|
-
const processor = new PublicProcessor(
|
|
557
|
+
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
|
|
558
|
+
const processor = new PublicProcessor(
|
|
559
|
+
globals,
|
|
560
|
+
guardedMerkleTrees,
|
|
561
|
+
contractsDB,
|
|
562
|
+
simulator,
|
|
563
|
+
new TestDateProvider(),
|
|
564
|
+
undefined,
|
|
565
|
+
createLogger('simulator:public-processor', bindings2),
|
|
566
|
+
);
|
|
530
567
|
|
|
531
568
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
532
569
|
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
@@ -636,9 +673,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
636
673
|
}
|
|
637
674
|
|
|
638
675
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
639
|
-
await this.
|
|
640
|
-
|
|
641
|
-
|
|
676
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
677
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
678
|
+
targetContractAddress,
|
|
679
|
+
functionSelector,
|
|
680
|
+
async call => {
|
|
681
|
+
await this.executeUtilityCall(call);
|
|
682
|
+
},
|
|
683
|
+
blockHeader,
|
|
684
|
+
this.jobId,
|
|
685
|
+
);
|
|
642
686
|
|
|
643
687
|
const call = new FunctionCall(
|
|
644
688
|
artifact.name,
|
|
@@ -654,7 +698,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
654
698
|
return this.executeUtilityCall(call);
|
|
655
699
|
}
|
|
656
700
|
|
|
657
|
-
private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
|
|
701
|
+
private async executeUtilityCall(call: FunctionCall, scopes?: AztecAddress[]): Promise<Fr[]> {
|
|
658
702
|
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
659
703
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
660
704
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
@@ -677,12 +721,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
677
721
|
this.keyStore,
|
|
678
722
|
this.addressStore,
|
|
679
723
|
this.stateMachine.node,
|
|
680
|
-
this.stateMachine.anchorBlockStore,
|
|
681
724
|
this.recipientTaggingStore,
|
|
682
725
|
this.senderAddressBookStore,
|
|
683
726
|
this.capsuleStore,
|
|
684
727
|
this.privateEventStore,
|
|
685
|
-
|
|
728
|
+
this.jobId,
|
|
729
|
+
undefined, // log
|
|
730
|
+
scopes, // scopes - used to filter notes by account
|
|
686
731
|
);
|
|
687
732
|
const acirExecutionResult = await new WASMSimulator()
|
|
688
733
|
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
package/src/rpc_translator.ts
CHANGED
|
@@ -6,11 +6,11 @@ import {
|
|
|
6
6
|
type IMiscOracle,
|
|
7
7
|
type IPrivateExecutionOracle,
|
|
8
8
|
type IUtilityExecutionOracle,
|
|
9
|
-
|
|
9
|
+
packAsHintedNote,
|
|
10
10
|
} from '@aztec/pxe/simulator';
|
|
11
11
|
import { type ContractArtifact, EventSelector, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
12
12
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
13
|
-
import {
|
|
13
|
+
import { BlockHash } from '@aztec/stdlib/block';
|
|
14
14
|
|
|
15
15
|
import type { IAvmExecutionOracle, ITxeExecutionOracle } from './oracle/interfaces.js';
|
|
16
16
|
import type { TXESessionStateHandler } from './txe_session.js';
|
|
@@ -346,34 +346,34 @@ export class RPCTranslator {
|
|
|
346
346
|
}
|
|
347
347
|
|
|
348
348
|
async utilityStorageRead(
|
|
349
|
+
foreignBlockHash: ForeignCallSingle,
|
|
349
350
|
foreignContractAddress: ForeignCallSingle,
|
|
350
351
|
foreignStartStorageSlot: ForeignCallSingle,
|
|
351
|
-
foreignBlockNumber: ForeignCallSingle,
|
|
352
352
|
foreignNumberOfElements: ForeignCallSingle,
|
|
353
353
|
) {
|
|
354
|
+
const blockHash = new BlockHash(fromSingle(foreignBlockHash));
|
|
354
355
|
const contractAddress = addressFromSingle(foreignContractAddress);
|
|
355
356
|
const startStorageSlot = fromSingle(foreignStartStorageSlot);
|
|
356
|
-
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
357
357
|
const numberOfElements = fromSingle(foreignNumberOfElements).toNumber();
|
|
358
358
|
|
|
359
359
|
const values = await this.handlerAsUtility().utilityStorageRead(
|
|
360
|
+
blockHash,
|
|
360
361
|
contractAddress,
|
|
361
362
|
startStorageSlot,
|
|
362
|
-
blockNumber,
|
|
363
363
|
numberOfElements,
|
|
364
364
|
);
|
|
365
365
|
|
|
366
366
|
return toForeignCallResult([toArray(values)]);
|
|
367
367
|
}
|
|
368
368
|
|
|
369
|
-
async utilityGetPublicDataWitness(
|
|
370
|
-
const
|
|
369
|
+
async utilityGetPublicDataWitness(foreignBlockHash: ForeignCallSingle, foreignLeafSlot: ForeignCallSingle) {
|
|
370
|
+
const blockHash = new BlockHash(fromSingle(foreignBlockHash));
|
|
371
371
|
const leafSlot = fromSingle(foreignLeafSlot);
|
|
372
372
|
|
|
373
|
-
const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(
|
|
373
|
+
const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(blockHash, leafSlot);
|
|
374
374
|
|
|
375
375
|
if (!witness) {
|
|
376
|
-
throw new Error(`Public data witness not found for slot ${leafSlot} at block ${
|
|
376
|
+
throw new Error(`Public data witness not found for slot ${leafSlot} at block ${blockHash.toString()}.`);
|
|
377
377
|
}
|
|
378
378
|
return toForeignCallResult(witness.toNoirRepresentation());
|
|
379
379
|
}
|
|
@@ -396,7 +396,7 @@ export class RPCTranslator {
|
|
|
396
396
|
foreignOffset: ForeignCallSingle,
|
|
397
397
|
foreignStatus: ForeignCallSingle,
|
|
398
398
|
foreignMaxNotes: ForeignCallSingle,
|
|
399
|
-
|
|
399
|
+
foreignPackedHintedNoteLength: ForeignCallSingle,
|
|
400
400
|
) {
|
|
401
401
|
// Parse Option<AztecAddress>: ownerIsSome is 0 for None, 1 for Some
|
|
402
402
|
const owner = fromSingle(foreignOwnerIsSome).toBool()
|
|
@@ -417,7 +417,7 @@ export class RPCTranslator {
|
|
|
417
417
|
const offset = fromSingle(foreignOffset).toNumber();
|
|
418
418
|
const status = fromSingle(foreignStatus).toNumber();
|
|
419
419
|
const maxNotes = fromSingle(foreignMaxNotes).toNumber();
|
|
420
|
-
const
|
|
420
|
+
const packedHintedNoteLength = fromSingle(foreignPackedHintedNoteLength).toNumber();
|
|
421
421
|
|
|
422
422
|
const noteDatas = await this.handlerAsUtility().utilityGetNotes(
|
|
423
423
|
owner,
|
|
@@ -438,13 +438,13 @@ export class RPCTranslator {
|
|
|
438
438
|
);
|
|
439
439
|
|
|
440
440
|
const returnDataAsArrayOfArrays = noteDatas.map(noteData =>
|
|
441
|
-
|
|
441
|
+
packAsHintedNote({
|
|
442
442
|
contractAddress: noteData.contractAddress,
|
|
443
443
|
owner: noteData.owner,
|
|
444
444
|
randomness: noteData.randomness,
|
|
445
445
|
storageSlot: noteData.storageSlot,
|
|
446
446
|
noteNonce: noteData.noteNonce,
|
|
447
|
-
|
|
447
|
+
isPending: noteData.isPending,
|
|
448
448
|
note: noteData.note,
|
|
449
449
|
}),
|
|
450
450
|
);
|
|
@@ -456,11 +456,7 @@ export class RPCTranslator {
|
|
|
456
456
|
|
|
457
457
|
// At last we convert the array of arrays to a bounded vec of arrays
|
|
458
458
|
return toForeignCallResult(
|
|
459
|
-
arrayOfArraysToBoundedVecOfArrays(
|
|
460
|
-
returnDataAsArrayOfForeignCallSingleArrays,
|
|
461
|
-
maxNotes,
|
|
462
|
-
packedRetrievedNoteLength,
|
|
463
|
-
),
|
|
459
|
+
arrayOfArraysToBoundedVecOfArrays(returnDataAsArrayOfForeignCallSingleArrays, maxNotes, packedHintedNoteLength),
|
|
464
460
|
);
|
|
465
461
|
}
|
|
466
462
|
|
|
@@ -516,6 +512,15 @@ export class RPCTranslator {
|
|
|
516
512
|
return toForeignCallResult([]);
|
|
517
513
|
}
|
|
518
514
|
|
|
515
|
+
async privateIsNullifierPending(foreignInnerNullifier: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
|
|
516
|
+
const innerNullifier = fromSingle(foreignInnerNullifier);
|
|
517
|
+
const contractAddress = addressFromSingle(foreignContractAddress);
|
|
518
|
+
|
|
519
|
+
const isPending = await this.handlerAsPrivate().privateIsNullifierPending(innerNullifier, contractAddress);
|
|
520
|
+
|
|
521
|
+
return toForeignCallResult([toSingle(new Fr(isPending))]);
|
|
522
|
+
}
|
|
523
|
+
|
|
519
524
|
async utilityCheckNullifierExists(foreignInnerNullifier: ForeignCallSingle) {
|
|
520
525
|
const innerNullifier = fromSingle(foreignInnerNullifier);
|
|
521
526
|
|
|
@@ -540,12 +545,23 @@ export class RPCTranslator {
|
|
|
540
545
|
);
|
|
541
546
|
}
|
|
542
547
|
|
|
543
|
-
async
|
|
548
|
+
async utilityTryGetPublicKeysAndPartialAddress(foreignAddress: ForeignCallSingle) {
|
|
544
549
|
const address = addressFromSingle(foreignAddress);
|
|
545
550
|
|
|
546
|
-
const
|
|
551
|
+
const result = await this.handlerAsUtility().utilityTryGetPublicKeysAndPartialAddress(address);
|
|
547
552
|
|
|
548
|
-
return
|
|
553
|
+
// We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
|
|
554
|
+
// with two fields: `some` (a boolean) and `value` (a field array in this case).
|
|
555
|
+
if (result === undefined) {
|
|
556
|
+
// No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size.
|
|
557
|
+
return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(13).fill(new Fr(0)))]);
|
|
558
|
+
} else {
|
|
559
|
+
// Data was found so we set `some` to 1 and return it along with `value`.
|
|
560
|
+
return toForeignCallResult([
|
|
561
|
+
toSingle(new Fr(1)),
|
|
562
|
+
toArray([...result.publicKeys.toFields(), result.partialAddress]),
|
|
563
|
+
]);
|
|
564
|
+
}
|
|
549
565
|
}
|
|
550
566
|
|
|
551
567
|
async utilityGetKeyValidationRequest(foreignPkMHash: ForeignCallSingle) {
|
|
@@ -568,17 +584,14 @@ export class RPCTranslator {
|
|
|
568
584
|
);
|
|
569
585
|
}
|
|
570
586
|
|
|
571
|
-
async utilityGetNullifierMembershipWitness(
|
|
572
|
-
|
|
573
|
-
foreignNullifier: ForeignCallSingle,
|
|
574
|
-
) {
|
|
575
|
-
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
587
|
+
async utilityGetNullifierMembershipWitness(foreignBlockHash: ForeignCallSingle, foreignNullifier: ForeignCallSingle) {
|
|
588
|
+
const blockHash = new BlockHash(fromSingle(foreignBlockHash));
|
|
576
589
|
const nullifier = fromSingle(foreignNullifier);
|
|
577
590
|
|
|
578
|
-
const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(
|
|
591
|
+
const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockHash, nullifier);
|
|
579
592
|
|
|
580
593
|
if (!witness) {
|
|
581
|
-
throw new Error(`Nullifier membership witness not found at block ${
|
|
594
|
+
throw new Error(`Nullifier membership witness not found at block ${blockHash}.`);
|
|
582
595
|
}
|
|
583
596
|
return toForeignCallResult(witness.toNoirRepresentation());
|
|
584
597
|
}
|
|
@@ -639,36 +652,49 @@ export class RPCTranslator {
|
|
|
639
652
|
return toForeignCallResult(header.toFields().map(toSingle));
|
|
640
653
|
}
|
|
641
654
|
|
|
642
|
-
async
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
foreignLeafValue: ForeignCallSingle,
|
|
655
|
+
async utilityGetNoteHashMembershipWitness(
|
|
656
|
+
foreignAnchorBlockHash: ForeignCallSingle,
|
|
657
|
+
foreignNoteHash: ForeignCallSingle,
|
|
646
658
|
) {
|
|
647
|
-
const
|
|
648
|
-
const
|
|
649
|
-
|
|
659
|
+
const blockHash = new BlockHash(fromSingle(foreignAnchorBlockHash));
|
|
660
|
+
const noteHash = fromSingle(foreignNoteHash);
|
|
661
|
+
|
|
662
|
+
const witness = await this.handlerAsUtility().utilityGetNoteHashMembershipWitness(blockHash, noteHash);
|
|
663
|
+
|
|
664
|
+
if (!witness) {
|
|
665
|
+
throw new Error(`Note hash ${noteHash} not found in the note hash tree at block ${blockHash.toString()}.`);
|
|
666
|
+
}
|
|
667
|
+
return toForeignCallResult(witness.toNoirRepresentation());
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
async utilityGetBlockHashMembershipWitness(
|
|
671
|
+
foreignAnchorBlockHash: ForeignCallSingle,
|
|
672
|
+
foreignBlockHash: ForeignCallSingle,
|
|
673
|
+
) {
|
|
674
|
+
const anchorBlockHash = new BlockHash(fromSingle(foreignAnchorBlockHash));
|
|
675
|
+
const blockHash = new BlockHash(fromSingle(foreignBlockHash));
|
|
650
676
|
|
|
651
|
-
const witness = await this.handlerAsUtility().
|
|
677
|
+
const witness = await this.handlerAsUtility().utilityGetBlockHashMembershipWitness(anchorBlockHash, blockHash);
|
|
652
678
|
|
|
653
679
|
if (!witness) {
|
|
654
680
|
throw new Error(
|
|
655
|
-
`
|
|
681
|
+
`Block hash ${blockHash.toString()} not found in the archive tree at anchor block ${anchorBlockHash.toString()}.`,
|
|
656
682
|
);
|
|
657
683
|
}
|
|
658
|
-
return toForeignCallResult(
|
|
684
|
+
return toForeignCallResult(witness.toNoirRepresentation());
|
|
659
685
|
}
|
|
660
686
|
|
|
661
687
|
async utilityGetLowNullifierMembershipWitness(
|
|
662
|
-
|
|
688
|
+
foreignBlockHash: ForeignCallSingle,
|
|
663
689
|
foreignNullifier: ForeignCallSingle,
|
|
664
690
|
) {
|
|
665
|
-
const
|
|
691
|
+
const blockHash = new BlockHash(fromSingle(foreignBlockHash));
|
|
666
692
|
const nullifier = fromSingle(foreignNullifier);
|
|
667
693
|
|
|
668
|
-
const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(
|
|
694
|
+
const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockHash, nullifier);
|
|
669
695
|
|
|
670
696
|
if (!witness) {
|
|
671
|
-
throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${
|
|
697
|
+
throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${blockHash}.`);
|
|
672
698
|
}
|
|
673
699
|
return toForeignCallResult(witness.toNoirRepresentation());
|
|
674
700
|
}
|
|
@@ -681,7 +707,7 @@ export class RPCTranslator {
|
|
|
681
707
|
return toForeignCallResult([]);
|
|
682
708
|
}
|
|
683
709
|
|
|
684
|
-
public async
|
|
710
|
+
public async utilityValidateAndStoreEnqueuedNotesAndEvents(
|
|
685
711
|
foreignContractAddress: ForeignCallSingle,
|
|
686
712
|
foreignNoteValidationRequestsArrayBaseSlot: ForeignCallSingle,
|
|
687
713
|
foreignEventValidationRequestsArrayBaseSlot: ForeignCallSingle,
|
|
@@ -690,7 +716,7 @@ export class RPCTranslator {
|
|
|
690
716
|
const noteValidationRequestsArrayBaseSlot = fromSingle(foreignNoteValidationRequestsArrayBaseSlot);
|
|
691
717
|
const eventValidationRequestsArrayBaseSlot = fromSingle(foreignEventValidationRequestsArrayBaseSlot);
|
|
692
718
|
|
|
693
|
-
await this.handlerAsUtility().
|
|
719
|
+
await this.handlerAsUtility().utilityValidateAndStoreEnqueuedNotesAndEvents(
|
|
694
720
|
contractAddress,
|
|
695
721
|
noteValidationRequestsArrayBaseSlot,
|
|
696
722
|
eventValidationRequestsArrayBaseSlot,
|
|
@@ -828,10 +854,11 @@ export class RPCTranslator {
|
|
|
828
854
|
return toForeignCallResult([]);
|
|
829
855
|
}
|
|
830
856
|
|
|
831
|
-
async avmOpcodeStorageRead(foreignSlot: ForeignCallSingle) {
|
|
857
|
+
async avmOpcodeStorageRead(foreignSlot: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
|
|
832
858
|
const slot = fromSingle(foreignSlot);
|
|
859
|
+
const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
|
|
833
860
|
|
|
834
|
-
const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot)).value;
|
|
861
|
+
const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot, contractAddress)).value;
|
|
835
862
|
|
|
836
863
|
return toForeignCallResult([toSingle(new Fr(value))]);
|
|
837
864
|
}
|
|
@@ -903,11 +930,10 @@ export class RPCTranslator {
|
|
|
903
930
|
return toForeignCallResult([]);
|
|
904
931
|
}
|
|
905
932
|
|
|
906
|
-
async avmOpcodeNullifierExists(
|
|
907
|
-
const
|
|
908
|
-
const targetAddress = AztecAddress.fromField(fromSingle(foreignTargetAddress));
|
|
933
|
+
async avmOpcodeNullifierExists(foreignSiloedNullifier: ForeignCallSingle) {
|
|
934
|
+
const siloedNullifier = fromSingle(foreignSiloedNullifier);
|
|
909
935
|
|
|
910
|
-
const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(
|
|
936
|
+
const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(siloedNullifier);
|
|
911
937
|
|
|
912
938
|
return toForeignCallResult([toSingle(new Fr(exists))]);
|
|
913
939
|
}
|