@aztec/txe 0.0.1-commit.6c91f13 → 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/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 +39 -24
- 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 -67
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +59 -178
- package/dest/state_machine/dummy_p2p_client.d.ts +8 -7
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +13 -10
- package/dest/state_machine/global_variable_builder.d.ts +2 -2
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +1 -1
- 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 +7 -6
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +10 -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 +34 -15
- 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 -5
- 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/oracle/interfaces.ts +2 -2
- package/src/oracle/txe_oracle_public_context.ts +6 -8
- package/src/oracle/txe_oracle_top_level_context.ts +75 -28
- package/src/rpc_translator.ts +76 -50
- package/src/state_machine/archiver.ts +54 -220
- package/src/state_machine/dummy_p2p_client.ts +18 -13
- package/src/state_machine/global_variable_builder.ts +1 -1
- package/src/state_machine/index.ts +48 -11
- package/src/state_machine/mock_epoch_cache.ts +10 -11
- package/src/state_machine/synchronizer.ts +2 -2
- package/src/txe_session.ts +43 -21
- package/src/utils/block_creation.ts +19 -16
- package/src/utils/tx_effect_creation.ts +3 -11
|
@@ -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,16 +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
|
-
|
|
363
|
+
this.stateMachine.contractSyncService,
|
|
364
|
+
this.jobId,
|
|
365
|
+
0, // totalPublicArgsCount
|
|
366
|
+
minRevertibleSideEffectCounter, // (start) sideEffectCounter
|
|
349
367
|
undefined, // log
|
|
350
|
-
|
|
368
|
+
effectiveScopes, // scopes
|
|
351
369
|
/**
|
|
352
370
|
* In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
353
371
|
* contract would perform, including setting senderForTags.
|
|
@@ -381,19 +399,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
381
399
|
}),
|
|
382
400
|
);
|
|
383
401
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
result = new PrivateExecutionResult(executionResult, Fr.ZERO, publicFunctionsCalldata);
|
|
402
|
+
noteCache.finish();
|
|
403
|
+
const nonceGenerator = noteCache.getNonceGenerator();
|
|
404
|
+
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
388
405
|
} catch (err) {
|
|
389
406
|
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
390
407
|
}
|
|
391
408
|
|
|
392
|
-
// According to the protocol rules,
|
|
393
|
-
//
|
|
394
|
-
//
|
|
395
|
-
const
|
|
396
|
-
|
|
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
|
+
);
|
|
397
417
|
|
|
398
418
|
const globals = makeGlobalVariables();
|
|
399
419
|
globals.blockNumber = blockNumber;
|
|
@@ -404,7 +424,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
404
424
|
|
|
405
425
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
406
426
|
|
|
407
|
-
const
|
|
427
|
+
const bindings = this.logger.getBindings();
|
|
428
|
+
const contractsDB = new PublicContractsDB(
|
|
429
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
430
|
+
bindings,
|
|
431
|
+
);
|
|
408
432
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
409
433
|
const config = PublicSimulatorConfig.from({
|
|
410
434
|
skipFeeEnforcement: true,
|
|
@@ -417,8 +441,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
417
441
|
globals,
|
|
418
442
|
guardedMerkleTrees,
|
|
419
443
|
contractsDB,
|
|
420
|
-
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
|
|
444
|
+
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
|
|
421
445
|
new TestDateProvider(),
|
|
446
|
+
undefined,
|
|
447
|
+
createLogger('simulator:public-processor', bindings),
|
|
422
448
|
);
|
|
423
449
|
|
|
424
450
|
const tx = await Tx.create({
|
|
@@ -515,7 +541,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
515
541
|
|
|
516
542
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
517
543
|
|
|
518
|
-
const
|
|
544
|
+
const bindings2 = this.logger.getBindings();
|
|
545
|
+
const contractsDB = new PublicContractsDB(
|
|
546
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
547
|
+
bindings2,
|
|
548
|
+
);
|
|
519
549
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
520
550
|
const config = PublicSimulatorConfig.from({
|
|
521
551
|
skipFeeEnforcement: true,
|
|
@@ -524,8 +554,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
524
554
|
collectStatistics: false,
|
|
525
555
|
collectCallMetadata: true,
|
|
526
556
|
});
|
|
527
|
-
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
|
|
528
|
-
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
|
+
);
|
|
529
567
|
|
|
530
568
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
531
569
|
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
@@ -635,9 +673,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
635
673
|
}
|
|
636
674
|
|
|
637
675
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
638
|
-
await this.
|
|
639
|
-
|
|
640
|
-
|
|
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
|
+
);
|
|
641
686
|
|
|
642
687
|
const call = new FunctionCall(
|
|
643
688
|
artifact.name,
|
|
@@ -653,7 +698,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
653
698
|
return this.executeUtilityCall(call);
|
|
654
699
|
}
|
|
655
700
|
|
|
656
|
-
private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
|
|
701
|
+
private async executeUtilityCall(call: FunctionCall, scopes?: AztecAddress[]): Promise<Fr[]> {
|
|
657
702
|
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
658
703
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
659
704
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
@@ -676,11 +721,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
676
721
|
this.keyStore,
|
|
677
722
|
this.addressStore,
|
|
678
723
|
this.stateMachine.node,
|
|
679
|
-
this.stateMachine.anchorBlockStore,
|
|
680
724
|
this.recipientTaggingStore,
|
|
681
725
|
this.senderAddressBookStore,
|
|
682
726
|
this.capsuleStore,
|
|
683
727
|
this.privateEventStore,
|
|
728
|
+
this.jobId,
|
|
729
|
+
undefined, // log
|
|
730
|
+
scopes, // scopes - used to filter notes by account
|
|
684
731
|
);
|
|
685
732
|
const acirExecutionResult = await new WASMSimulator()
|
|
686
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
|
}
|