@aztec/txe 3.0.3 → 3.9.9-nightly.20260312
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 +3 -0
- package/dest/constants.d.ts.map +1 -0
- package/dest/constants.js +2 -0
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +85 -52
- package/dest/oracle/interfaces.d.ts +9 -6
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.d.ts +4 -4
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +9 -11
- package/dest/oracle/txe_oracle_top_level_context.d.ts +21 -13
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +180 -72
- package/dest/rpc_translator.d.ts +29 -17
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +124 -57
- package/dest/state_machine/archiver.d.ts +20 -55
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +67 -108
- package/dest/state_machine/dummy_p2p_client.d.ts +20 -15
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +42 -25
- package/dest/state_machine/global_variable_builder.d.ts +4 -3
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +13 -1
- 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 +41 -24
- package/dest/state_machine/mock_epoch_cache.d.ts +9 -6
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +14 -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 +22 -11
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +154 -49
- package/dest/util/encoding.d.ts +617 -18
- package/dest/util/encoding.d.ts.map +1 -1
- package/dest/util/txe_account_store.d.ts +10 -0
- package/dest/util/txe_account_store.d.ts.map +1 -0
- package/dest/util/{txe_account_data_provider.js → txe_account_store.js} +1 -1
- package/dest/util/txe_public_contract_data_source.d.ts +5 -6
- package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
- package/dest/util/txe_public_contract_data_source.js +12 -29
- package/dest/utils/block_creation.d.ts +18 -4
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +37 -3
- 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 +3 -0
- package/src/index.ts +97 -60
- package/src/oracle/interfaces.ts +11 -4
- package/src/oracle/txe_oracle_public_context.ts +9 -16
- package/src/oracle/txe_oracle_top_level_context.ts +223 -110
- package/src/rpc_translator.ts +141 -58
- package/src/state_machine/archiver.ts +61 -129
- package/src/state_machine/dummy_p2p_client.ts +58 -33
- package/src/state_machine/global_variable_builder.ts +19 -2
- package/src/state_machine/index.ts +61 -22
- package/src/state_machine/mock_epoch_cache.ts +15 -11
- package/src/state_machine/synchronizer.ts +2 -2
- package/src/txe_session.ts +213 -94
- package/src/util/{txe_account_data_provider.ts → txe_account_store.ts} +1 -1
- package/src/util/txe_public_contract_data_source.ts +16 -42
- package/src/utils/block_creation.ts +47 -14
- package/src/utils/tx_effect_creation.ts +3 -11
- package/dest/util/txe_account_data_provider.d.ts +0 -10
- package/dest/util/txe_account_data_provider.d.ts.map +0 -1
- package/dest/util/txe_contract_data_provider.d.ts +0 -12
- package/dest/util/txe_contract_data_provider.d.ts.map +0 -1
- package/dest/util/txe_contract_data_provider.js +0 -22
- package/src/util/txe_contract_data_provider.ts +0 -36
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
|
-
import { type ContractArtifact, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
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';
|
|
@@ -30,6 +30,9 @@ import {
|
|
|
30
30
|
toSingle,
|
|
31
31
|
} from './util/encoding.js';
|
|
32
32
|
|
|
33
|
+
const MAX_EVENT_LEN = 10; // This is MAX_MESSAGE_CONTENT_LEN - PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN
|
|
34
|
+
const MAX_PRIVATE_EVENTS_PER_TXE_QUERY = 5;
|
|
35
|
+
|
|
33
36
|
export class UnavailableOracleError extends Error {
|
|
34
37
|
constructor(oracleName: string) {
|
|
35
38
|
super(`${oracleName} oracles not available with the current handler`);
|
|
@@ -156,6 +159,12 @@ export class RPCTranslator {
|
|
|
156
159
|
|
|
157
160
|
// TXE-specific oracles
|
|
158
161
|
|
|
162
|
+
txeGetDefaultAddress() {
|
|
163
|
+
const defaultAddress = this.handlerAsTxe().txeGetDefaultAddress();
|
|
164
|
+
|
|
165
|
+
return toForeignCallResult([toSingle(defaultAddress)]);
|
|
166
|
+
}
|
|
167
|
+
|
|
159
168
|
async txeGetNextBlockNumber() {
|
|
160
169
|
const nextBlockNumber = await this.handlerAsTxe().txeGetNextBlockNumber();
|
|
161
170
|
|
|
@@ -267,6 +276,46 @@ export class RPCTranslator {
|
|
|
267
276
|
]);
|
|
268
277
|
}
|
|
269
278
|
|
|
279
|
+
async txeGetPrivateEvents(
|
|
280
|
+
foreignSelector: ForeignCallSingle,
|
|
281
|
+
foreignContractAddress: ForeignCallSingle,
|
|
282
|
+
foreignScope: ForeignCallSingle,
|
|
283
|
+
) {
|
|
284
|
+
const selector = EventSelector.fromField(fromSingle(foreignSelector));
|
|
285
|
+
const contractAddress = addressFromSingle(foreignContractAddress);
|
|
286
|
+
const scope = addressFromSingle(foreignScope);
|
|
287
|
+
|
|
288
|
+
// TODO(F-335): Avoid doing the following 2 calls here.
|
|
289
|
+
{
|
|
290
|
+
await this.handlerAsTxe().syncContractNonOracleMethod(contractAddress, scope, this.stateHandler.getCurrentJob());
|
|
291
|
+
// We cycle job to commit the stores after the contract sync.
|
|
292
|
+
await this.stateHandler.cycleJob();
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const events = await this.handlerAsTxe().txeGetPrivateEvents(selector, contractAddress, scope);
|
|
296
|
+
|
|
297
|
+
if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
|
|
298
|
+
throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (events.some(e => e.length > MAX_EVENT_LEN)) {
|
|
302
|
+
throw new Error(`Some private event has length larger than maxLen ${MAX_EVENT_LEN}`);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// This is a workaround as Noir does not currently let us return nested structs with arrays. We instead return a raw
|
|
306
|
+
// multidimensional array in get_private_events_oracle and create the BoundedVecs here.
|
|
307
|
+
const rawArrayStorage = events
|
|
308
|
+
.map(e => e.concat(Array(MAX_EVENT_LEN - e.length).fill(new Fr(0))))
|
|
309
|
+
.concat(Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(Array(MAX_EVENT_LEN).fill(new Fr(0))))
|
|
310
|
+
.flat();
|
|
311
|
+
const eventLengths = events
|
|
312
|
+
.map(e => new Fr(e.length))
|
|
313
|
+
.concat(Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(new Fr(0)));
|
|
314
|
+
const queryLength = new Fr(events.length);
|
|
315
|
+
|
|
316
|
+
return toForeignCallResult([toArray(rawArrayStorage), toArray(eventLengths), toSingle(queryLength)]);
|
|
317
|
+
}
|
|
318
|
+
|
|
270
319
|
privateStoreInExecutionCache(foreignValues: ForeignCallArray, foreignHash: ForeignCallSingle) {
|
|
271
320
|
const values = fromArray(foreignValues);
|
|
272
321
|
const hash = fromSingle(foreignHash);
|
|
@@ -286,7 +335,7 @@ export class RPCTranslator {
|
|
|
286
335
|
|
|
287
336
|
// When the argument is a slice, noir automatically adds a length field to oracle call.
|
|
288
337
|
// When the argument is an array, we add the field length manually to the signature.
|
|
289
|
-
|
|
338
|
+
async utilityLog(
|
|
290
339
|
foreignLevel: ForeignCallSingle,
|
|
291
340
|
foreignMessage: ForeignCallArray,
|
|
292
341
|
_foreignLength: ForeignCallSingle,
|
|
@@ -298,40 +347,40 @@ export class RPCTranslator {
|
|
|
298
347
|
.join('');
|
|
299
348
|
const fields = fromArray(foreignFields);
|
|
300
349
|
|
|
301
|
-
this.handlerAsMisc().
|
|
350
|
+
await this.handlerAsMisc().utilityLog(level, message, fields);
|
|
302
351
|
|
|
303
352
|
return toForeignCallResult([]);
|
|
304
353
|
}
|
|
305
354
|
|
|
306
355
|
async utilityStorageRead(
|
|
356
|
+
foreignBlockHash: ForeignCallSingle,
|
|
307
357
|
foreignContractAddress: ForeignCallSingle,
|
|
308
358
|
foreignStartStorageSlot: ForeignCallSingle,
|
|
309
|
-
foreignBlockNumber: ForeignCallSingle,
|
|
310
359
|
foreignNumberOfElements: ForeignCallSingle,
|
|
311
360
|
) {
|
|
361
|
+
const blockHash = new BlockHash(fromSingle(foreignBlockHash));
|
|
312
362
|
const contractAddress = addressFromSingle(foreignContractAddress);
|
|
313
363
|
const startStorageSlot = fromSingle(foreignStartStorageSlot);
|
|
314
|
-
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
315
364
|
const numberOfElements = fromSingle(foreignNumberOfElements).toNumber();
|
|
316
365
|
|
|
317
366
|
const values = await this.handlerAsUtility().utilityStorageRead(
|
|
367
|
+
blockHash,
|
|
318
368
|
contractAddress,
|
|
319
369
|
startStorageSlot,
|
|
320
|
-
blockNumber,
|
|
321
370
|
numberOfElements,
|
|
322
371
|
);
|
|
323
372
|
|
|
324
373
|
return toForeignCallResult([toArray(values)]);
|
|
325
374
|
}
|
|
326
375
|
|
|
327
|
-
async utilityGetPublicDataWitness(
|
|
328
|
-
const
|
|
376
|
+
async utilityGetPublicDataWitness(foreignBlockHash: ForeignCallSingle, foreignLeafSlot: ForeignCallSingle) {
|
|
377
|
+
const blockHash = new BlockHash(fromSingle(foreignBlockHash));
|
|
329
378
|
const leafSlot = fromSingle(foreignLeafSlot);
|
|
330
379
|
|
|
331
|
-
const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(
|
|
380
|
+
const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(blockHash, leafSlot);
|
|
332
381
|
|
|
333
382
|
if (!witness) {
|
|
334
|
-
throw new Error(`Public data witness not found for slot ${leafSlot} at block ${
|
|
383
|
+
throw new Error(`Public data witness not found for slot ${leafSlot} at block ${blockHash.toString()}.`);
|
|
335
384
|
}
|
|
336
385
|
return toForeignCallResult(witness.toNoirRepresentation());
|
|
337
386
|
}
|
|
@@ -354,7 +403,7 @@ export class RPCTranslator {
|
|
|
354
403
|
foreignOffset: ForeignCallSingle,
|
|
355
404
|
foreignStatus: ForeignCallSingle,
|
|
356
405
|
foreignMaxNotes: ForeignCallSingle,
|
|
357
|
-
|
|
406
|
+
foreignPackedHintedNoteLength: ForeignCallSingle,
|
|
358
407
|
) {
|
|
359
408
|
// Parse Option<AztecAddress>: ownerIsSome is 0 for None, 1 for Some
|
|
360
409
|
const owner = fromSingle(foreignOwnerIsSome).toBool()
|
|
@@ -375,7 +424,7 @@ export class RPCTranslator {
|
|
|
375
424
|
const offset = fromSingle(foreignOffset).toNumber();
|
|
376
425
|
const status = fromSingle(foreignStatus).toNumber();
|
|
377
426
|
const maxNotes = fromSingle(foreignMaxNotes).toNumber();
|
|
378
|
-
const
|
|
427
|
+
const packedHintedNoteLength = fromSingle(foreignPackedHintedNoteLength).toNumber();
|
|
379
428
|
|
|
380
429
|
const noteDatas = await this.handlerAsUtility().utilityGetNotes(
|
|
381
430
|
owner,
|
|
@@ -396,13 +445,13 @@ export class RPCTranslator {
|
|
|
396
445
|
);
|
|
397
446
|
|
|
398
447
|
const returnDataAsArrayOfArrays = noteDatas.map(noteData =>
|
|
399
|
-
|
|
448
|
+
packAsHintedNote({
|
|
400
449
|
contractAddress: noteData.contractAddress,
|
|
401
450
|
owner: noteData.owner,
|
|
402
451
|
randomness: noteData.randomness,
|
|
403
452
|
storageSlot: noteData.storageSlot,
|
|
404
453
|
noteNonce: noteData.noteNonce,
|
|
405
|
-
|
|
454
|
+
isPending: noteData.isPending,
|
|
406
455
|
note: noteData.note,
|
|
407
456
|
}),
|
|
408
457
|
);
|
|
@@ -414,11 +463,7 @@ export class RPCTranslator {
|
|
|
414
463
|
|
|
415
464
|
// At last we convert the array of arrays to a bounded vec of arrays
|
|
416
465
|
return toForeignCallResult(
|
|
417
|
-
arrayOfArraysToBoundedVecOfArrays(
|
|
418
|
-
returnDataAsArrayOfForeignCallSingleArrays,
|
|
419
|
-
maxNotes,
|
|
420
|
-
packedRetrievedNoteLength,
|
|
421
|
-
),
|
|
466
|
+
arrayOfArraysToBoundedVecOfArrays(returnDataAsArrayOfForeignCallSingleArrays, maxNotes, packedHintedNoteLength),
|
|
422
467
|
);
|
|
423
468
|
}
|
|
424
469
|
|
|
@@ -474,6 +519,15 @@ export class RPCTranslator {
|
|
|
474
519
|
return toForeignCallResult([]);
|
|
475
520
|
}
|
|
476
521
|
|
|
522
|
+
async privateIsNullifierPending(foreignInnerNullifier: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
|
|
523
|
+
const innerNullifier = fromSingle(foreignInnerNullifier);
|
|
524
|
+
const contractAddress = addressFromSingle(foreignContractAddress);
|
|
525
|
+
|
|
526
|
+
const isPending = await this.handlerAsPrivate().privateIsNullifierPending(innerNullifier, contractAddress);
|
|
527
|
+
|
|
528
|
+
return toForeignCallResult([toSingle(new Fr(isPending))]);
|
|
529
|
+
}
|
|
530
|
+
|
|
477
531
|
async utilityCheckNullifierExists(foreignInnerNullifier: ForeignCallSingle) {
|
|
478
532
|
const innerNullifier = fromSingle(foreignInnerNullifier);
|
|
479
533
|
|
|
@@ -498,12 +552,23 @@ export class RPCTranslator {
|
|
|
498
552
|
);
|
|
499
553
|
}
|
|
500
554
|
|
|
501
|
-
async
|
|
555
|
+
async utilityTryGetPublicKeysAndPartialAddress(foreignAddress: ForeignCallSingle) {
|
|
502
556
|
const address = addressFromSingle(foreignAddress);
|
|
503
557
|
|
|
504
|
-
const
|
|
558
|
+
const result = await this.handlerAsUtility().utilityTryGetPublicKeysAndPartialAddress(address);
|
|
505
559
|
|
|
506
|
-
return
|
|
560
|
+
// We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
|
|
561
|
+
// with two fields: `some` (a boolean) and `value` (a field array in this case).
|
|
562
|
+
if (result === undefined) {
|
|
563
|
+
// No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size.
|
|
564
|
+
return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(13).fill(new Fr(0)))]);
|
|
565
|
+
} else {
|
|
566
|
+
// Data was found so we set `some` to 1 and return it along with `value`.
|
|
567
|
+
return toForeignCallResult([
|
|
568
|
+
toSingle(new Fr(1)),
|
|
569
|
+
toArray([...result.publicKeys.toFields(), result.partialAddress]),
|
|
570
|
+
]);
|
|
571
|
+
}
|
|
507
572
|
}
|
|
508
573
|
|
|
509
574
|
async utilityGetKeyValidationRequest(foreignPkMHash: ForeignCallSingle) {
|
|
@@ -526,17 +591,14 @@ export class RPCTranslator {
|
|
|
526
591
|
);
|
|
527
592
|
}
|
|
528
593
|
|
|
529
|
-
async utilityGetNullifierMembershipWitness(
|
|
530
|
-
|
|
531
|
-
foreignNullifier: ForeignCallSingle,
|
|
532
|
-
) {
|
|
533
|
-
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
594
|
+
async utilityGetNullifierMembershipWitness(foreignBlockHash: ForeignCallSingle, foreignNullifier: ForeignCallSingle) {
|
|
595
|
+
const blockHash = new BlockHash(fromSingle(foreignBlockHash));
|
|
534
596
|
const nullifier = fromSingle(foreignNullifier);
|
|
535
597
|
|
|
536
|
-
const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(
|
|
598
|
+
const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockHash, nullifier);
|
|
537
599
|
|
|
538
600
|
if (!witness) {
|
|
539
|
-
throw new Error(`Nullifier membership witness not found at block ${
|
|
601
|
+
throw new Error(`Nullifier membership witness not found at block ${blockHash}.`);
|
|
540
602
|
}
|
|
541
603
|
return toForeignCallResult(witness.toNoirRepresentation());
|
|
542
604
|
}
|
|
@@ -580,8 +642,8 @@ export class RPCTranslator {
|
|
|
580
642
|
return toForeignCallResult([toSingle(new Fr(isRevertible))]);
|
|
581
643
|
}
|
|
582
644
|
|
|
583
|
-
|
|
584
|
-
const context =
|
|
645
|
+
utilityGetUtilityContext() {
|
|
646
|
+
const context = this.handlerAsUtility().utilityGetUtilityContext();
|
|
585
647
|
|
|
586
648
|
return toForeignCallResult(context.toNoirRepresentation());
|
|
587
649
|
}
|
|
@@ -597,36 +659,49 @@ export class RPCTranslator {
|
|
|
597
659
|
return toForeignCallResult(header.toFields().map(toSingle));
|
|
598
660
|
}
|
|
599
661
|
|
|
600
|
-
async
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
foreignLeafValue: ForeignCallSingle,
|
|
662
|
+
async utilityGetNoteHashMembershipWitness(
|
|
663
|
+
foreignAnchorBlockHash: ForeignCallSingle,
|
|
664
|
+
foreignNoteHash: ForeignCallSingle,
|
|
604
665
|
) {
|
|
605
|
-
const
|
|
606
|
-
const
|
|
607
|
-
const leafValue = fromSingle(foreignLeafValue);
|
|
666
|
+
const blockHash = new BlockHash(fromSingle(foreignAnchorBlockHash));
|
|
667
|
+
const noteHash = fromSingle(foreignNoteHash);
|
|
608
668
|
|
|
609
|
-
const witness = await this.handlerAsUtility().
|
|
669
|
+
const witness = await this.handlerAsUtility().utilityGetNoteHashMembershipWitness(blockHash, noteHash);
|
|
670
|
+
|
|
671
|
+
if (!witness) {
|
|
672
|
+
throw new Error(`Note hash ${noteHash} not found in the note hash tree at block ${blockHash.toString()}.`);
|
|
673
|
+
}
|
|
674
|
+
return toForeignCallResult(witness.toNoirRepresentation());
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
async utilityGetBlockHashMembershipWitness(
|
|
678
|
+
foreignAnchorBlockHash: ForeignCallSingle,
|
|
679
|
+
foreignBlockHash: ForeignCallSingle,
|
|
680
|
+
) {
|
|
681
|
+
const anchorBlockHash = new BlockHash(fromSingle(foreignAnchorBlockHash));
|
|
682
|
+
const blockHash = new BlockHash(fromSingle(foreignBlockHash));
|
|
683
|
+
|
|
684
|
+
const witness = await this.handlerAsUtility().utilityGetBlockHashMembershipWitness(anchorBlockHash, blockHash);
|
|
610
685
|
|
|
611
686
|
if (!witness) {
|
|
612
687
|
throw new Error(
|
|
613
|
-
`
|
|
688
|
+
`Block hash ${blockHash.toString()} not found in the archive tree at anchor block ${anchorBlockHash.toString()}.`,
|
|
614
689
|
);
|
|
615
690
|
}
|
|
616
|
-
return toForeignCallResult(
|
|
691
|
+
return toForeignCallResult(witness.toNoirRepresentation());
|
|
617
692
|
}
|
|
618
693
|
|
|
619
694
|
async utilityGetLowNullifierMembershipWitness(
|
|
620
|
-
|
|
695
|
+
foreignBlockHash: ForeignCallSingle,
|
|
621
696
|
foreignNullifier: ForeignCallSingle,
|
|
622
697
|
) {
|
|
623
|
-
const
|
|
698
|
+
const blockHash = new BlockHash(fromSingle(foreignBlockHash));
|
|
624
699
|
const nullifier = fromSingle(foreignNullifier);
|
|
625
700
|
|
|
626
|
-
const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(
|
|
701
|
+
const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockHash, nullifier);
|
|
627
702
|
|
|
628
703
|
if (!witness) {
|
|
629
|
-
throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${
|
|
704
|
+
throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${blockHash}.`);
|
|
630
705
|
}
|
|
631
706
|
return toForeignCallResult(witness.toNoirRepresentation());
|
|
632
707
|
}
|
|
@@ -639,7 +714,7 @@ export class RPCTranslator {
|
|
|
639
714
|
return toForeignCallResult([]);
|
|
640
715
|
}
|
|
641
716
|
|
|
642
|
-
public async
|
|
717
|
+
public async utilityValidateAndStoreEnqueuedNotesAndEvents(
|
|
643
718
|
foreignContractAddress: ForeignCallSingle,
|
|
644
719
|
foreignNoteValidationRequestsArrayBaseSlot: ForeignCallSingle,
|
|
645
720
|
foreignEventValidationRequestsArrayBaseSlot: ForeignCallSingle,
|
|
@@ -648,7 +723,7 @@ export class RPCTranslator {
|
|
|
648
723
|
const noteValidationRequestsArrayBaseSlot = fromSingle(foreignNoteValidationRequestsArrayBaseSlot);
|
|
649
724
|
const eventValidationRequestsArrayBaseSlot = fromSingle(foreignEventValidationRequestsArrayBaseSlot);
|
|
650
725
|
|
|
651
|
-
await this.handlerAsUtility().
|
|
726
|
+
await this.handlerAsUtility().utilityValidateAndStoreEnqueuedNotesAndEvents(
|
|
652
727
|
contractAddress,
|
|
653
728
|
noteValidationRequestsArrayBaseSlot,
|
|
654
729
|
eventValidationRequestsArrayBaseSlot,
|
|
@@ -781,15 +856,16 @@ export class RPCTranslator {
|
|
|
781
856
|
|
|
782
857
|
// AVM opcodes
|
|
783
858
|
|
|
784
|
-
|
|
859
|
+
avmOpcodeEmitPublicLog(_foreignMessage: ForeignCallArray) {
|
|
785
860
|
// TODO(#8811): Implement
|
|
786
861
|
return toForeignCallResult([]);
|
|
787
862
|
}
|
|
788
863
|
|
|
789
|
-
async avmOpcodeStorageRead(foreignSlot: ForeignCallSingle) {
|
|
864
|
+
async avmOpcodeStorageRead(foreignSlot: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
|
|
790
865
|
const slot = fromSingle(foreignSlot);
|
|
866
|
+
const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
|
|
791
867
|
|
|
792
|
-
const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot)).value;
|
|
868
|
+
const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot, contractAddress)).value;
|
|
793
869
|
|
|
794
870
|
return toForeignCallResult([toSingle(new Fr(value))]);
|
|
795
871
|
}
|
|
@@ -861,11 +937,10 @@ export class RPCTranslator {
|
|
|
861
937
|
return toForeignCallResult([]);
|
|
862
938
|
}
|
|
863
939
|
|
|
864
|
-
async avmOpcodeNullifierExists(
|
|
865
|
-
const
|
|
866
|
-
const targetAddress = AztecAddress.fromField(fromSingle(foreignTargetAddress));
|
|
940
|
+
async avmOpcodeNullifierExists(foreignSiloedNullifier: ForeignCallSingle) {
|
|
941
|
+
const siloedNullifier = fromSingle(foreignSiloedNullifier);
|
|
867
942
|
|
|
868
|
-
const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(
|
|
943
|
+
const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(siloedNullifier);
|
|
869
944
|
|
|
870
945
|
return toForeignCallResult([toSingle(new Fr(exists))]);
|
|
871
946
|
}
|
|
@@ -970,12 +1045,15 @@ export class RPCTranslator {
|
|
|
970
1045
|
args,
|
|
971
1046
|
argsHash,
|
|
972
1047
|
isStaticCall,
|
|
1048
|
+
this.stateHandler.getCurrentJob(),
|
|
973
1049
|
);
|
|
974
1050
|
|
|
1051
|
+
// TODO(F-335): Avoid doing the following call here.
|
|
1052
|
+
await this.stateHandler.cycleJob();
|
|
975
1053
|
return toForeignCallResult([toArray(returnValues)]);
|
|
976
1054
|
}
|
|
977
1055
|
|
|
978
|
-
async
|
|
1056
|
+
async txeExecuteUtilityFunction(
|
|
979
1057
|
foreignTargetContractAddress: ForeignCallSingle,
|
|
980
1058
|
foreignFunctionSelector: ForeignCallSingle,
|
|
981
1059
|
foreignArgs: ForeignCallArray,
|
|
@@ -984,12 +1062,15 @@ export class RPCTranslator {
|
|
|
984
1062
|
const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
|
|
985
1063
|
const args = fromArray(foreignArgs);
|
|
986
1064
|
|
|
987
|
-
const returnValues = await this.handlerAsTxe().
|
|
1065
|
+
const returnValues = await this.handlerAsTxe().txeExecuteUtilityFunction(
|
|
988
1066
|
targetContractAddress,
|
|
989
1067
|
functionSelector,
|
|
990
1068
|
args,
|
|
1069
|
+
this.stateHandler.getCurrentJob(),
|
|
991
1070
|
);
|
|
992
1071
|
|
|
1072
|
+
// TODO(F-335): Avoid doing the following call here.
|
|
1073
|
+
await this.stateHandler.cycleJob();
|
|
993
1074
|
return toForeignCallResult([toArray(returnValues)]);
|
|
994
1075
|
}
|
|
995
1076
|
|
|
@@ -1006,6 +1087,8 @@ export class RPCTranslator {
|
|
|
1006
1087
|
|
|
1007
1088
|
const returnValues = await this.handlerAsTxe().txePublicCallNewFlow(from, address, calldata, isStaticCall);
|
|
1008
1089
|
|
|
1090
|
+
// TODO(F-335): Avoid doing the following call here.
|
|
1091
|
+
await this.stateHandler.cycleJob();
|
|
1009
1092
|
return toForeignCallResult([toArray(returnValues)]);
|
|
1010
1093
|
}
|
|
1011
1094
|
|
|
@@ -1,165 +1,97 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ArchiverDataSourceBase, ArchiverDataStoreUpdater, KVArchiverDataStore } from '@aztec/archiver';
|
|
2
2
|
import { GENESIS_ARCHIVE_ROOT } from '@aztec/constants';
|
|
3
|
-
import {
|
|
3
|
+
import { CheckpointNumber, type EpochNumber, type SlotNumber } from '@aztec/foundation/branded-types';
|
|
4
4
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
5
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
6
6
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
7
|
-
import type {
|
|
8
|
-
import type {
|
|
9
|
-
import type { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
10
|
-
import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
7
|
+
import type { CheckpointId, L2BlockId, L2TipId, L2Tips, ValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
8
|
+
import type { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
11
9
|
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
12
|
-
import type { BlockHeader } from '@aztec/stdlib/tx';
|
|
13
|
-
import type { UInt64 } from '@aztec/stdlib/types';
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
public override async addBlocks(blocks: PublishedL2Block[]): Promise<boolean> {
|
|
24
|
-
const opResults = await Promise.all([
|
|
25
|
-
this.store.addLogs(blocks.map(block => block.block)),
|
|
26
|
-
this.store.addBlocks(blocks),
|
|
27
|
-
]);
|
|
28
|
-
|
|
29
|
-
return opResults.every(Boolean);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Gets the number of the latest L2 block processed by the block source implementation.
|
|
34
|
-
* @returns The number of the latest L2 block processed by the block source implementation.
|
|
35
|
-
*/
|
|
36
|
-
public getBlockNumber(): Promise<BlockNumber> {
|
|
37
|
-
return this.store.getSynchedL2BlockNumber();
|
|
38
|
-
}
|
|
11
|
+
/**
|
|
12
|
+
* TXE Archiver implementation.
|
|
13
|
+
* Provides most of the endpoints needed by the node for reading from and writing to state,
|
|
14
|
+
* without needing any of the extra overhead that the Archiver itself requires (i.e. an L1 client).
|
|
15
|
+
*/
|
|
16
|
+
export class TXEArchiver extends ArchiverDataSourceBase {
|
|
17
|
+
private readonly updater = new ArchiverDataStoreUpdater(this.store);
|
|
39
18
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
*/
|
|
44
|
-
public getProvenBlockNumber(): Promise<BlockNumber> {
|
|
45
|
-
return this.store.getSynchedL2BlockNumber();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Gets a published l2 block. If a negative number is passed, the block returned is the most recent.
|
|
50
|
-
* @param number - The block number to return (inclusive).
|
|
51
|
-
* @returns The requested L2 block.
|
|
52
|
-
*/
|
|
53
|
-
public override async getPublishedBlock(number: number): Promise<PublishedL2Block | undefined> {
|
|
54
|
-
// If the number provided is -ve, then return the latest block.
|
|
55
|
-
if (number < 0) {
|
|
56
|
-
number = await this.store.getSynchedL2BlockNumber();
|
|
57
|
-
}
|
|
58
|
-
if (number == 0) {
|
|
59
|
-
return undefined;
|
|
60
|
-
}
|
|
61
|
-
const blocks = await this.store.getPublishedBlocks(BlockNumber(number), 1);
|
|
62
|
-
return blocks.length === 0 ? undefined : blocks[0];
|
|
19
|
+
constructor(db: AztecAsyncKVStore) {
|
|
20
|
+
const store = new KVArchiverDataStore(db, 9999, { epochDuration: 32 });
|
|
21
|
+
super(store);
|
|
63
22
|
}
|
|
64
23
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
* @param number - The block number to return (inclusive).
|
|
68
|
-
* @returns The requested L2 block.
|
|
69
|
-
*/
|
|
70
|
-
public getBlock(number: number | 'latest'): Promise<L2Block | undefined> {
|
|
71
|
-
return this.getPublishedBlock(number != 'latest' ? number : -1).then(block => block?.block);
|
|
24
|
+
public async addCheckpoints(checkpoints: PublishedCheckpoint[], result?: ValidateCheckpointResult): Promise<void> {
|
|
25
|
+
await this.updater.addCheckpoints(checkpoints, result);
|
|
72
26
|
}
|
|
73
27
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
* @param number - The block number to return or 'latest' for the most recent one.
|
|
77
|
-
* @returns The requested L2 block header.
|
|
78
|
-
*/
|
|
79
|
-
public async getBlockHeader(number: number | 'latest'): Promise<BlockHeader | undefined> {
|
|
80
|
-
if (number === 'latest') {
|
|
81
|
-
number = await this.store.getSynchedL2BlockNumber();
|
|
82
|
-
}
|
|
83
|
-
if (number === 0) {
|
|
84
|
-
return undefined;
|
|
85
|
-
}
|
|
86
|
-
const headers = await this.store.getBlockHeaders(BlockNumber(number), 1);
|
|
87
|
-
return headers.length === 0 ? undefined : headers[0];
|
|
28
|
+
public getRollupAddress(): Promise<EthAddress> {
|
|
29
|
+
throw new Error('TXE Archiver does not implement "getRollupAddress"');
|
|
88
30
|
}
|
|
89
31
|
|
|
90
|
-
public
|
|
91
|
-
|
|
32
|
+
public getRegistryAddress(): Promise<EthAddress> {
|
|
33
|
+
throw new Error('TXE Archiver does not implement "getRegistryAddress"');
|
|
92
34
|
}
|
|
93
35
|
|
|
94
|
-
public
|
|
95
|
-
throw new Error('TXE Archiver does not implement "
|
|
36
|
+
public getL1Constants(): Promise<L1RollupConstants> {
|
|
37
|
+
throw new Error('TXE Archiver does not implement "getL1Constants"');
|
|
96
38
|
}
|
|
97
39
|
|
|
98
|
-
public
|
|
99
|
-
|
|
40
|
+
public getGenesisValues(): Promise<{ genesisArchiveRoot: Fr }> {
|
|
41
|
+
return Promise.resolve({ genesisArchiveRoot: new Fr(GENESIS_ARCHIVE_ROOT) });
|
|
100
42
|
}
|
|
101
43
|
|
|
102
|
-
public
|
|
103
|
-
throw new Error('TXE Archiver does not implement "
|
|
44
|
+
public getL1Timestamp(): Promise<bigint | undefined> {
|
|
45
|
+
throw new Error('TXE Archiver does not implement "getL1Timestamp"');
|
|
104
46
|
}
|
|
105
47
|
|
|
106
|
-
public
|
|
107
|
-
|
|
108
|
-
|
|
48
|
+
public async getL2Tips(): Promise<L2Tips> {
|
|
49
|
+
// In TXE there is no possibility of reorgs and no blocks are ever getting proven so we just set 'latest', 'proven'
|
|
50
|
+
// and 'finalized' to the latest block.
|
|
51
|
+
const blockHeader = await this.getBlockHeader('latest');
|
|
52
|
+
if (!blockHeader) {
|
|
53
|
+
throw new Error('L2Tips requested from TXE Archiver but no block header found');
|
|
54
|
+
}
|
|
109
55
|
|
|
110
|
-
|
|
111
|
-
|
|
56
|
+
const number = blockHeader.globalVariables.blockNumber;
|
|
57
|
+
const hash = (await blockHeader.hash()).toString();
|
|
58
|
+
const checkpointedBlock = await this.getCheckpointedBlock(number);
|
|
59
|
+
if (!checkpointedBlock) {
|
|
60
|
+
throw new Error(`L2Tips requested from TXE Archiver but no checkpointed block found for block number ${number}`);
|
|
61
|
+
}
|
|
62
|
+
// TXE uses 1-block-per-checkpoint for testing simplicity, so we can use block number as checkpoint number.
|
|
63
|
+
// This uses the deprecated fromBlockNumber method intentionally for the TXE testing environment.
|
|
64
|
+
const checkpoint = await this.store.getRangeOfCheckpoints(CheckpointNumber.fromBlockNumber(number), 1);
|
|
65
|
+
if (checkpoint.length === 0) {
|
|
66
|
+
throw new Error(`L2Tips requested from TXE Archiver but no checkpoint found for block number ${number}`);
|
|
67
|
+
}
|
|
68
|
+
const blockId: L2BlockId = { number, hash };
|
|
69
|
+
const checkpointId: CheckpointId = {
|
|
70
|
+
number: checkpoint[0].checkpointNumber,
|
|
71
|
+
hash: checkpoint[0].header.hash().toString(),
|
|
72
|
+
};
|
|
73
|
+
const tipId: L2TipId = { block: blockId, checkpoint: checkpointId };
|
|
74
|
+
return {
|
|
75
|
+
proposed: blockId,
|
|
76
|
+
proven: tipId,
|
|
77
|
+
finalized: tipId,
|
|
78
|
+
checkpointed: tipId,
|
|
79
|
+
};
|
|
112
80
|
}
|
|
113
81
|
|
|
114
|
-
public
|
|
115
|
-
throw new Error('TXE Archiver does not implement "
|
|
82
|
+
public getSyncedL2SlotNumber(): Promise<SlotNumber | undefined> {
|
|
83
|
+
throw new Error('TXE Archiver does not implement "getSyncedL2SlotNumber"');
|
|
116
84
|
}
|
|
117
85
|
|
|
118
|
-
public
|
|
119
|
-
throw new Error('TXE Archiver does not implement "
|
|
86
|
+
public getSyncedL2EpochNumber(): Promise<EpochNumber | undefined> {
|
|
87
|
+
throw new Error('TXE Archiver does not implement "getSyncedL2EpochNumber"');
|
|
120
88
|
}
|
|
121
89
|
|
|
122
90
|
public isEpochComplete(_epochNumber: EpochNumber): Promise<boolean> {
|
|
123
91
|
throw new Error('TXE Archiver does not implement "isEpochComplete"');
|
|
124
92
|
}
|
|
125
93
|
|
|
126
|
-
public getL2Tips(): Promise<L2Tips> {
|
|
127
|
-
throw new Error('TXE Archiver does not implement "getL2Tips"');
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
public getL1Constants(): Promise<L1RollupConstants> {
|
|
131
|
-
throw new Error('TXE Archiver does not implement "getL2Constants"');
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
public getGenesisValues(): Promise<{ genesisArchiveRoot: Fr }> {
|
|
135
|
-
return Promise.resolve({ genesisArchiveRoot: new Fr(GENESIS_ARCHIVE_ROOT) });
|
|
136
|
-
}
|
|
137
|
-
|
|
138
94
|
public syncImmediate(): Promise<void> {
|
|
139
95
|
throw new Error('TXE Archiver does not implement "syncImmediate"');
|
|
140
96
|
}
|
|
141
|
-
|
|
142
|
-
public getContract(_address: AztecAddress, _timestamp?: UInt64): Promise<ContractInstanceWithAddress | undefined> {
|
|
143
|
-
throw new Error('TXE Archiver does not implement "getContract"');
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
public getRollupAddress(): Promise<EthAddress> {
|
|
147
|
-
throw new Error('TXE Archiver does not implement "getRollupAddress"');
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
public getRegistryAddress(): Promise<EthAddress> {
|
|
151
|
-
throw new Error('TXE Archiver does not implement "getRegistryAddress"');
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
public getL1Timestamp(): Promise<bigint> {
|
|
155
|
-
throw new Error('TXE Archiver does not implement "getL1Timestamp"');
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
public isPendingChainInvalid(): Promise<boolean> {
|
|
159
|
-
return Promise.resolve(false);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
public override getPendingChainValidationStatus(): Promise<ValidateBlockResult> {
|
|
163
|
-
return Promise.resolve({ valid: true });
|
|
164
|
-
}
|
|
165
97
|
}
|