@aztec/txe 0.0.1-commit.d3ec352c → 0.0.1-commit.e61ad554
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 +3 -2
- package/dest/oracle/interfaces.d.ts +6 -4
- 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 +7 -8
- package/dest/oracle/txe_oracle_top_level_context.d.ts +20 -11
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +100 -63
- package/dest/rpc_translator.d.ts +23 -11
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +91 -38
- package/dest/state_machine/archiver.d.ts +21 -57
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +61 -107
- 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 +16 -11
- 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 +5 -5
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +32 -20
- 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/state_machine/synchronizer.js +2 -2
- package/dest/txe_session.d.ts +18 -10
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +91 -45
- package/dest/util/encoding.d.ts +618 -19
- package/dest/util/encoding.d.ts.map +1 -1
- package/dest/util/encoding.js +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_contract_store.d.ts +12 -0
- package/dest/util/txe_contract_store.d.ts.map +1 -0
- package/dest/util/{txe_contract_data_provider.js → txe_contract_store.js} +3 -3
- package/dest/util/txe_public_contract_data_source.d.ts +5 -5
- package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
- package/dest/util/txe_public_contract_data_source.js +11 -11
- package/dest/utils/block_creation.d.ts +19 -5
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +36 -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 +4 -7
- package/package.json +16 -16
- package/src/constants.ts +3 -0
- package/src/index.ts +15 -12
- package/src/oracle/interfaces.ts +5 -3
- package/src/oracle/txe_oracle_public_context.ts +7 -12
- package/src/oracle/txe_oracle_top_level_context.ts +149 -88
- package/src/rpc_translator.ts +113 -49
- package/src/state_machine/archiver.ts +57 -131
- package/src/state_machine/dummy_p2p_client.ts +21 -14
- package/src/state_machine/global_variable_builder.ts +19 -2
- package/src/state_machine/index.ts +41 -18
- package/src/state_machine/mock_epoch_cache.ts +10 -11
- package/src/state_machine/synchronizer.ts +3 -4
- package/src/txe_session.ts +187 -76
- package/src/util/encoding.ts +1 -1
- package/src/util/{txe_account_data_provider.ts → txe_account_store.ts} +1 -1
- package/src/util/{txe_contract_data_provider.ts → txe_contract_store.ts} +3 -3
- package/src/util/txe_public_contract_data_source.ts +10 -10
- package/src/utils/block_creation.ts +46 -15
- package/src/utils/tx_effect_creation.ts +4 -12
- 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/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 { L2BlockHash } 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 = 12; // This is MAX_MESSAGE_CONTENT_LEN - PRIVATE_EVENT_RESERVED_FIELDS
|
|
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,39 @@ 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
|
+
const events = await this.handlerAsTxe().txeGetPrivateEvents(selector, contractAddress, scope);
|
|
289
|
+
|
|
290
|
+
if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
|
|
291
|
+
throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (events.some(e => e.length > MAX_EVENT_LEN)) {
|
|
295
|
+
throw new Error(`Some private event has length larger than maxLen ${MAX_EVENT_LEN}`);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// This is a workaround as Noir does not currently let us return nested structs with arrays. We instead return a raw
|
|
299
|
+
// multidimensional array in get_private_events_oracle and create the BoundedVecs here.
|
|
300
|
+
const rawArrayStorage = events
|
|
301
|
+
.map(e => e.concat(Array(MAX_EVENT_LEN - e.length).fill(new Fr(0))))
|
|
302
|
+
.concat(Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(Array(MAX_EVENT_LEN).fill(new Fr(0))))
|
|
303
|
+
.flat();
|
|
304
|
+
const eventLengths = events
|
|
305
|
+
.map(e => new Fr(e.length))
|
|
306
|
+
.concat(Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(new Fr(0)));
|
|
307
|
+
const queryLength = new Fr(events.length);
|
|
308
|
+
|
|
309
|
+
return toForeignCallResult([toArray(rawArrayStorage), toArray(eventLengths), toSingle(queryLength)]);
|
|
310
|
+
}
|
|
311
|
+
|
|
270
312
|
privateStoreInExecutionCache(foreignValues: ForeignCallArray, foreignHash: ForeignCallSingle) {
|
|
271
313
|
const values = fromArray(foreignValues);
|
|
272
314
|
const hash = fromSingle(foreignHash);
|
|
@@ -304,40 +346,41 @@ export class RPCTranslator {
|
|
|
304
346
|
}
|
|
305
347
|
|
|
306
348
|
async utilityStorageRead(
|
|
349
|
+
foreignBlockHash: ForeignCallSingle,
|
|
307
350
|
foreignContractAddress: ForeignCallSingle,
|
|
308
351
|
foreignStartStorageSlot: ForeignCallSingle,
|
|
309
|
-
foreignBlockNumber: ForeignCallSingle,
|
|
310
352
|
foreignNumberOfElements: ForeignCallSingle,
|
|
311
353
|
) {
|
|
354
|
+
const blockHash = L2BlockHash.fromString(foreignBlockHash);
|
|
312
355
|
const contractAddress = addressFromSingle(foreignContractAddress);
|
|
313
356
|
const startStorageSlot = fromSingle(foreignStartStorageSlot);
|
|
314
|
-
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
315
357
|
const numberOfElements = fromSingle(foreignNumberOfElements).toNumber();
|
|
316
358
|
|
|
317
359
|
const values = await this.handlerAsUtility().utilityStorageRead(
|
|
360
|
+
blockHash,
|
|
318
361
|
contractAddress,
|
|
319
362
|
startStorageSlot,
|
|
320
|
-
blockNumber,
|
|
321
363
|
numberOfElements,
|
|
322
364
|
);
|
|
323
365
|
|
|
324
366
|
return toForeignCallResult([toArray(values)]);
|
|
325
367
|
}
|
|
326
368
|
|
|
327
|
-
async utilityGetPublicDataWitness(
|
|
328
|
-
const
|
|
369
|
+
async utilityGetPublicDataWitness(foreignBlockHash: ForeignCallSingle, foreignLeafSlot: ForeignCallSingle) {
|
|
370
|
+
const blockHash = L2BlockHash.fromString(foreignBlockHash);
|
|
329
371
|
const leafSlot = fromSingle(foreignLeafSlot);
|
|
330
372
|
|
|
331
|
-
const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(
|
|
373
|
+
const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(blockHash, leafSlot);
|
|
332
374
|
|
|
333
375
|
if (!witness) {
|
|
334
|
-
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()}.`);
|
|
335
377
|
}
|
|
336
378
|
return toForeignCallResult(witness.toNoirRepresentation());
|
|
337
379
|
}
|
|
338
380
|
|
|
339
381
|
async utilityGetNotes(
|
|
340
|
-
|
|
382
|
+
foreignOwnerIsSome: ForeignCallSingle,
|
|
383
|
+
foreignOwnerValue: ForeignCallSingle,
|
|
341
384
|
foreignStorageSlot: ForeignCallSingle,
|
|
342
385
|
foreignNumSelects: ForeignCallSingle,
|
|
343
386
|
foreignSelectByIndexes: ForeignCallArray,
|
|
@@ -353,9 +396,12 @@ export class RPCTranslator {
|
|
|
353
396
|
foreignOffset: ForeignCallSingle,
|
|
354
397
|
foreignStatus: ForeignCallSingle,
|
|
355
398
|
foreignMaxNotes: ForeignCallSingle,
|
|
356
|
-
|
|
399
|
+
foreignPackedHintedNoteLength: ForeignCallSingle,
|
|
357
400
|
) {
|
|
358
|
-
|
|
401
|
+
// Parse Option<AztecAddress>: ownerIsSome is 0 for None, 1 for Some
|
|
402
|
+
const owner = fromSingle(foreignOwnerIsSome).toBool()
|
|
403
|
+
? AztecAddress.fromField(fromSingle(foreignOwnerValue))
|
|
404
|
+
: undefined;
|
|
359
405
|
const storageSlot = fromSingle(foreignStorageSlot);
|
|
360
406
|
const numSelects = fromSingle(foreignNumSelects).toNumber();
|
|
361
407
|
const selectByIndexes = fromArray(foreignSelectByIndexes).map(fr => fr.toNumber());
|
|
@@ -371,7 +417,7 @@ export class RPCTranslator {
|
|
|
371
417
|
const offset = fromSingle(foreignOffset).toNumber();
|
|
372
418
|
const status = fromSingle(foreignStatus).toNumber();
|
|
373
419
|
const maxNotes = fromSingle(foreignMaxNotes).toNumber();
|
|
374
|
-
const
|
|
420
|
+
const packedHintedNoteLength = fromSingle(foreignPackedHintedNoteLength).toNumber();
|
|
375
421
|
|
|
376
422
|
const noteDatas = await this.handlerAsUtility().utilityGetNotes(
|
|
377
423
|
owner,
|
|
@@ -391,7 +437,17 @@ export class RPCTranslator {
|
|
|
391
437
|
status,
|
|
392
438
|
);
|
|
393
439
|
|
|
394
|
-
const returnDataAsArrayOfArrays = noteDatas.map(
|
|
440
|
+
const returnDataAsArrayOfArrays = noteDatas.map(noteData =>
|
|
441
|
+
packAsHintedNote({
|
|
442
|
+
contractAddress: noteData.contractAddress,
|
|
443
|
+
owner: noteData.owner,
|
|
444
|
+
randomness: noteData.randomness,
|
|
445
|
+
storageSlot: noteData.storageSlot,
|
|
446
|
+
noteNonce: noteData.noteNonce,
|
|
447
|
+
isPending: noteData.isPending,
|
|
448
|
+
note: noteData.note,
|
|
449
|
+
}),
|
|
450
|
+
);
|
|
395
451
|
|
|
396
452
|
// Now we convert each sub-array to an array of ForeignCallSingles
|
|
397
453
|
const returnDataAsArrayOfForeignCallSingleArrays = returnDataAsArrayOfArrays.map(subArray =>
|
|
@@ -400,11 +456,7 @@ export class RPCTranslator {
|
|
|
400
456
|
|
|
401
457
|
// At last we convert the array of arrays to a bounded vec of arrays
|
|
402
458
|
return toForeignCallResult(
|
|
403
|
-
arrayOfArraysToBoundedVecOfArrays(
|
|
404
|
-
returnDataAsArrayOfForeignCallSingleArrays,
|
|
405
|
-
maxNotes,
|
|
406
|
-
packedRetrievedNoteLength,
|
|
407
|
-
),
|
|
459
|
+
arrayOfArraysToBoundedVecOfArrays(returnDataAsArrayOfForeignCallSingleArrays, maxNotes, packedHintedNoteLength),
|
|
408
460
|
);
|
|
409
461
|
}
|
|
410
462
|
|
|
@@ -460,6 +512,15 @@ export class RPCTranslator {
|
|
|
460
512
|
return toForeignCallResult([]);
|
|
461
513
|
}
|
|
462
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
|
+
|
|
463
524
|
async utilityCheckNullifierExists(foreignInnerNullifier: ForeignCallSingle) {
|
|
464
525
|
const innerNullifier = fromSingle(foreignInnerNullifier);
|
|
465
526
|
|
|
@@ -512,17 +573,14 @@ export class RPCTranslator {
|
|
|
512
573
|
);
|
|
513
574
|
}
|
|
514
575
|
|
|
515
|
-
async utilityGetNullifierMembershipWitness(
|
|
516
|
-
|
|
517
|
-
foreignNullifier: ForeignCallSingle,
|
|
518
|
-
) {
|
|
519
|
-
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
576
|
+
async utilityGetNullifierMembershipWitness(foreignBlockHash: ForeignCallSingle, foreignNullifier: ForeignCallSingle) {
|
|
577
|
+
const blockHash = L2BlockHash.fromString(foreignBlockHash);
|
|
520
578
|
const nullifier = fromSingle(foreignNullifier);
|
|
521
579
|
|
|
522
|
-
const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(
|
|
580
|
+
const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockHash, nullifier);
|
|
523
581
|
|
|
524
582
|
if (!witness) {
|
|
525
|
-
throw new Error(`Nullifier membership witness not found at block ${
|
|
583
|
+
throw new Error(`Nullifier membership witness not found at block ${blockHash}.`);
|
|
526
584
|
}
|
|
527
585
|
return toForeignCallResult(witness.toNoirRepresentation());
|
|
528
586
|
}
|
|
@@ -566,8 +624,8 @@ export class RPCTranslator {
|
|
|
566
624
|
return toForeignCallResult([toSingle(new Fr(isRevertible))]);
|
|
567
625
|
}
|
|
568
626
|
|
|
569
|
-
|
|
570
|
-
const context =
|
|
627
|
+
utilityGetUtilityContext() {
|
|
628
|
+
const context = this.handlerAsUtility().utilityGetUtilityContext();
|
|
571
629
|
|
|
572
630
|
return toForeignCallResult(context.toNoirRepresentation());
|
|
573
631
|
}
|
|
@@ -583,36 +641,41 @@ export class RPCTranslator {
|
|
|
583
641
|
return toForeignCallResult(header.toFields().map(toSingle));
|
|
584
642
|
}
|
|
585
643
|
|
|
586
|
-
async
|
|
587
|
-
|
|
588
|
-
foreignTreeId: ForeignCallSingle,
|
|
589
|
-
foreignLeafValue: ForeignCallSingle,
|
|
590
|
-
) {
|
|
591
|
-
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
592
|
-
const treeId = fromSingle(foreignTreeId).toNumber();
|
|
644
|
+
async utilityGetNoteHashMembershipWitness(foreignBlockHash: ForeignCallSingle, foreignLeafValue: ForeignCallSingle) {
|
|
645
|
+
const blockHash = L2BlockHash.fromString(foreignBlockHash);
|
|
593
646
|
const leafValue = fromSingle(foreignLeafValue);
|
|
594
647
|
|
|
595
|
-
const witness = await this.handlerAsUtility().
|
|
648
|
+
const witness = await this.handlerAsUtility().utilityGetNoteHashMembershipWitness(blockHash, leafValue);
|
|
596
649
|
|
|
597
650
|
if (!witness) {
|
|
598
|
-
throw new Error(
|
|
599
|
-
`Membership witness in tree ${MerkleTreeId[treeId]} not found for value ${leafValue} at block ${blockNumber}.`,
|
|
600
|
-
);
|
|
651
|
+
throw new Error(`Note hash ${leafValue} not found in the note hash tree at block ${blockHash.toString()}.`);
|
|
601
652
|
}
|
|
602
|
-
return toForeignCallResult(
|
|
653
|
+
return toForeignCallResult(witness.toNoirRepresentation());
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
async utilityGetArchiveMembershipWitness(foreignBlockHash: ForeignCallSingle, foreignLeafValue: ForeignCallSingle) {
|
|
657
|
+
const blockHash = L2BlockHash.fromString(foreignBlockHash);
|
|
658
|
+
const leafValue = fromSingle(foreignLeafValue);
|
|
659
|
+
|
|
660
|
+
const witness = await this.handlerAsUtility().utilityGetArchiveMembershipWitness(blockHash, leafValue);
|
|
661
|
+
|
|
662
|
+
if (!witness) {
|
|
663
|
+
throw new Error(`Block hash ${leafValue} not found in the archive tree at block ${blockHash.toString()}.`);
|
|
664
|
+
}
|
|
665
|
+
return toForeignCallResult(witness.toNoirRepresentation());
|
|
603
666
|
}
|
|
604
667
|
|
|
605
668
|
async utilityGetLowNullifierMembershipWitness(
|
|
606
|
-
|
|
669
|
+
foreignBlockHash: ForeignCallSingle,
|
|
607
670
|
foreignNullifier: ForeignCallSingle,
|
|
608
671
|
) {
|
|
609
|
-
const
|
|
672
|
+
const blockHash = L2BlockHash.fromString(foreignBlockHash);
|
|
610
673
|
const nullifier = fromSingle(foreignNullifier);
|
|
611
674
|
|
|
612
|
-
const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(
|
|
675
|
+
const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockHash, nullifier);
|
|
613
676
|
|
|
614
677
|
if (!witness) {
|
|
615
|
-
throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${
|
|
678
|
+
throw new Error(`Low nullifier witness not found for nullifier ${nullifier} at block ${blockHash}.`);
|
|
616
679
|
}
|
|
617
680
|
return toForeignCallResult(witness.toNoirRepresentation());
|
|
618
681
|
}
|
|
@@ -625,7 +688,7 @@ export class RPCTranslator {
|
|
|
625
688
|
return toForeignCallResult([]);
|
|
626
689
|
}
|
|
627
690
|
|
|
628
|
-
public async
|
|
691
|
+
public async utilityValidateAndStoreEnqueuedNotesAndEvents(
|
|
629
692
|
foreignContractAddress: ForeignCallSingle,
|
|
630
693
|
foreignNoteValidationRequestsArrayBaseSlot: ForeignCallSingle,
|
|
631
694
|
foreignEventValidationRequestsArrayBaseSlot: ForeignCallSingle,
|
|
@@ -634,7 +697,7 @@ export class RPCTranslator {
|
|
|
634
697
|
const noteValidationRequestsArrayBaseSlot = fromSingle(foreignNoteValidationRequestsArrayBaseSlot);
|
|
635
698
|
const eventValidationRequestsArrayBaseSlot = fromSingle(foreignEventValidationRequestsArrayBaseSlot);
|
|
636
699
|
|
|
637
|
-
await this.handlerAsUtility().
|
|
700
|
+
await this.handlerAsUtility().utilityValidateAndStoreEnqueuedNotesAndEvents(
|
|
638
701
|
contractAddress,
|
|
639
702
|
noteValidationRequestsArrayBaseSlot,
|
|
640
703
|
eventValidationRequestsArrayBaseSlot,
|
|
@@ -772,10 +835,11 @@ export class RPCTranslator {
|
|
|
772
835
|
return toForeignCallResult([]);
|
|
773
836
|
}
|
|
774
837
|
|
|
775
|
-
async avmOpcodeStorageRead(foreignSlot: ForeignCallSingle) {
|
|
838
|
+
async avmOpcodeStorageRead(foreignSlot: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
|
|
776
839
|
const slot = fromSingle(foreignSlot);
|
|
840
|
+
const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
|
|
777
841
|
|
|
778
|
-
const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot)).value;
|
|
842
|
+
const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot, contractAddress)).value;
|
|
779
843
|
|
|
780
844
|
return toForeignCallResult([toSingle(new Fr(value))]);
|
|
781
845
|
}
|
|
@@ -1,169 +1,95 @@
|
|
|
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
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
5
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
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
|
-
|
|
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);
|
|
22
18
|
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
this.store.addBlocks(blocks),
|
|
27
|
-
]);
|
|
28
|
-
|
|
29
|
-
return opResults.every(Boolean);
|
|
19
|
+
constructor(db: AztecAsyncKVStore) {
|
|
20
|
+
const store = new KVArchiverDataStore(db, 9999, { epochDuration: 32 });
|
|
21
|
+
super(store);
|
|
30
22
|
}
|
|
31
23
|
|
|
32
|
-
|
|
33
|
-
|
|
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();
|
|
24
|
+
public async addCheckpoints(checkpoints: PublishedCheckpoint[], result?: ValidateCheckpointResult): Promise<void> {
|
|
25
|
+
await this.updater.addCheckpoints(checkpoints, result);
|
|
38
26
|
}
|
|
39
27
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
* @returns The number of the latest L2 block proven seen by the block source implementation.
|
|
43
|
-
*/
|
|
44
|
-
public getProvenBlockNumber(): Promise<BlockNumber> {
|
|
45
|
-
return this.store.getSynchedL2BlockNumber();
|
|
28
|
+
public getRollupAddress(): Promise<EthAddress> {
|
|
29
|
+
throw new Error('TXE Archiver does not implement "getRollupAddress"');
|
|
46
30
|
}
|
|
47
31
|
|
|
48
|
-
|
|
49
|
-
|
|
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];
|
|
32
|
+
public getRegistryAddress(): Promise<EthAddress> {
|
|
33
|
+
throw new Error('TXE Archiver does not implement "getRegistryAddress"');
|
|
63
34
|
}
|
|
64
35
|
|
|
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);
|
|
36
|
+
public getL1Constants(): Promise<L1RollupConstants> {
|
|
37
|
+
throw new Error('TXE Archiver does not implement "getL1Constants"');
|
|
72
38
|
}
|
|
73
39
|
|
|
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];
|
|
40
|
+
public getGenesisValues(): Promise<{ genesisArchiveRoot: Fr }> {
|
|
41
|
+
return Promise.resolve({ genesisArchiveRoot: new Fr(GENESIS_ARCHIVE_ROOT) });
|
|
88
42
|
}
|
|
89
43
|
|
|
90
|
-
public
|
|
91
|
-
|
|
44
|
+
public getL1Timestamp(): Promise<bigint | undefined> {
|
|
45
|
+
throw new Error('TXE Archiver does not implement "getL1Timestamp"');
|
|
92
46
|
}
|
|
93
47
|
|
|
94
|
-
public
|
|
95
|
-
|
|
96
|
-
|
|
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
|
+
}
|
|
97
55
|
|
|
98
|
-
|
|
99
|
-
|
|
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
|
+
const checkpoint = await this.store.getRangeOfCheckpoints(CheckpointNumber.fromBlockNumber(number), 1);
|
|
63
|
+
if (checkpoint.length === 0) {
|
|
64
|
+
throw new Error(`L2Tips requested from TXE Archiver but no checkpoint found for block number ${number}`);
|
|
65
|
+
}
|
|
66
|
+
const blockId: L2BlockId = { number, hash };
|
|
67
|
+
const checkpointId: CheckpointId = {
|
|
68
|
+
number: checkpoint[0].checkpointNumber,
|
|
69
|
+
hash: checkpoint[0].header.hash().toString(),
|
|
70
|
+
};
|
|
71
|
+
const tipId: L2TipId = { block: blockId, checkpoint: checkpointId };
|
|
72
|
+
return {
|
|
73
|
+
proposed: blockId,
|
|
74
|
+
proven: tipId,
|
|
75
|
+
finalized: tipId,
|
|
76
|
+
checkpointed: tipId,
|
|
77
|
+
};
|
|
100
78
|
}
|
|
101
79
|
|
|
102
80
|
public getL2SlotNumber(): Promise<SlotNumber | undefined> {
|
|
103
81
|
throw new Error('TXE Archiver does not implement "getL2SlotNumber"');
|
|
104
82
|
}
|
|
105
83
|
|
|
106
|
-
public getL2EpochNumber(): Promise<EpochNumber> {
|
|
84
|
+
public getL2EpochNumber(): Promise<EpochNumber | undefined> {
|
|
107
85
|
throw new Error('TXE Archiver does not implement "getL2EpochNumber"');
|
|
108
86
|
}
|
|
109
87
|
|
|
110
|
-
public getCheckpointsForEpoch(_epochNumber: EpochNumber): Promise<Checkpoint[]> {
|
|
111
|
-
throw new Error('TXE Archiver does not implement "getCheckpointsForEpoch"');
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
public getBlocksForEpoch(_epochNumber: EpochNumber): Promise<L2Block[]> {
|
|
115
|
-
throw new Error('TXE Archiver does not implement "getBlocksForEpoch"');
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
public getBlockHeadersForEpoch(_epochNumber: EpochNumber): Promise<BlockHeader[]> {
|
|
119
|
-
throw new Error('TXE Archiver does not implement "getBlockHeadersForEpoch"');
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
public getL1ToL2MessagesForCheckpoint(_checkpointNumber: CheckpointNumber): Promise<Fr[]> {
|
|
123
|
-
throw new Error('TXE Archiver does not implement "getL1ToL2MessagesForCheckpoint"');
|
|
124
|
-
}
|
|
125
|
-
|
|
126
88
|
public isEpochComplete(_epochNumber: EpochNumber): Promise<boolean> {
|
|
127
89
|
throw new Error('TXE Archiver does not implement "isEpochComplete"');
|
|
128
90
|
}
|
|
129
91
|
|
|
130
|
-
public getL2Tips(): Promise<L2Tips> {
|
|
131
|
-
throw new Error('TXE Archiver does not implement "getL2Tips"');
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
public getL1Constants(): Promise<L1RollupConstants> {
|
|
135
|
-
throw new Error('TXE Archiver does not implement "getL2Constants"');
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
public getGenesisValues(): Promise<{ genesisArchiveRoot: Fr }> {
|
|
139
|
-
return Promise.resolve({ genesisArchiveRoot: new Fr(GENESIS_ARCHIVE_ROOT) });
|
|
140
|
-
}
|
|
141
|
-
|
|
142
92
|
public syncImmediate(): Promise<void> {
|
|
143
93
|
throw new Error('TXE Archiver does not implement "syncImmediate"');
|
|
144
94
|
}
|
|
145
|
-
|
|
146
|
-
public getContract(_address: AztecAddress, _timestamp?: UInt64): Promise<ContractInstanceWithAddress | undefined> {
|
|
147
|
-
throw new Error('TXE Archiver does not implement "getContract"');
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
public getRollupAddress(): Promise<EthAddress> {
|
|
151
|
-
throw new Error('TXE Archiver does not implement "getRollupAddress"');
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
public getRegistryAddress(): Promise<EthAddress> {
|
|
155
|
-
throw new Error('TXE Archiver does not implement "getRegistryAddress"');
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
public getL1Timestamp(): Promise<bigint> {
|
|
159
|
-
throw new Error('TXE Archiver does not implement "getL1Timestamp"');
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
public isPendingChainInvalid(): Promise<boolean> {
|
|
163
|
-
return Promise.resolve(false);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
public override getPendingChainValidationStatus(): Promise<ValidateBlockResult> {
|
|
167
|
-
return Promise.resolve({ valid: true });
|
|
168
|
-
}
|
|
169
95
|
}
|
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
ENR,
|
|
5
5
|
P2P,
|
|
6
6
|
P2PBlockReceivedCallback,
|
|
7
|
+
P2PCheckpointReceivedCallback,
|
|
7
8
|
P2PConfig,
|
|
8
9
|
P2PSyncState,
|
|
9
10
|
PeerId,
|
|
@@ -14,14 +15,10 @@ import type {
|
|
|
14
15
|
} from '@aztec/p2p';
|
|
15
16
|
import type { EthAddress, L2BlockStreamEvent, L2Tips } from '@aztec/stdlib/block';
|
|
16
17
|
import type { PeerInfo } from '@aztec/stdlib/interfaces/server';
|
|
17
|
-
import type {
|
|
18
|
+
import type { BlockProposal, CheckpointAttestation, CheckpointProposal } from '@aztec/stdlib/p2p';
|
|
18
19
|
import type { Tx, TxHash } from '@aztec/stdlib/tx';
|
|
19
20
|
|
|
20
21
|
export class DummyP2P implements P2P {
|
|
21
|
-
public broadcastAttestations(_attestations: BlockAttestation[]): Promise<void> {
|
|
22
|
-
return Promise.resolve();
|
|
23
|
-
}
|
|
24
|
-
|
|
25
22
|
public validate(_txs: Tx[]): Promise<void> {
|
|
26
23
|
return Promise.resolve();
|
|
27
24
|
}
|
|
@@ -46,10 +43,22 @@ export class DummyP2P implements P2P {
|
|
|
46
43
|
throw new Error('DummyP2P does not implement "broadcastProposal"');
|
|
47
44
|
}
|
|
48
45
|
|
|
46
|
+
public broadcastCheckpointProposal(_proposal: CheckpointProposal): Promise<void> {
|
|
47
|
+
throw new Error('DummyP2P does not implement "broadcastCheckpointProposal"');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public broadcastCheckpointAttestations(_attestations: CheckpointAttestation[]): Promise<void> {
|
|
51
|
+
throw new Error('DummyP2P does not implement "broadcastCheckpointAttestations"');
|
|
52
|
+
}
|
|
53
|
+
|
|
49
54
|
public registerBlockProposalHandler(_handler: P2PBlockReceivedCallback): void {
|
|
50
55
|
throw new Error('DummyP2P does not implement "registerBlockProposalHandler"');
|
|
51
56
|
}
|
|
52
57
|
|
|
58
|
+
public registerCheckpointProposalHandler(_handler: P2PCheckpointReceivedCallback): void {
|
|
59
|
+
throw new Error('DummyP2P does not implement "registerCheckpointProposalHandler"');
|
|
60
|
+
}
|
|
61
|
+
|
|
53
62
|
public requestTxs(_txHashes: TxHash[]): Promise<(Tx | undefined)[]> {
|
|
54
63
|
throw new Error('DummyP2P does not implement "requestTxs"');
|
|
55
64
|
}
|
|
@@ -79,7 +88,9 @@ export class DummyP2P implements P2P {
|
|
|
79
88
|
}
|
|
80
89
|
|
|
81
90
|
public getTxStatus(_txHash: TxHash): Promise<'pending' | 'mined' | undefined> {
|
|
82
|
-
|
|
91
|
+
// In TXE there is no concept of transactions but we need to implement this because of tagging. We return 'mined'
|
|
92
|
+
// tx status for any tx hash.
|
|
93
|
+
return Promise.resolve('mined');
|
|
83
94
|
}
|
|
84
95
|
|
|
85
96
|
public iteratePendingTxs(): AsyncIterableIterator<Tx> {
|
|
@@ -118,16 +129,12 @@ export class DummyP2P implements P2P {
|
|
|
118
129
|
throw new Error('DummyP2P does not implement "getTxsByHash"');
|
|
119
130
|
}
|
|
120
131
|
|
|
121
|
-
public
|
|
122
|
-
throw new Error('DummyP2P does not implement "
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
public deleteAttestation(_attestation: BlockAttestation): Promise<void> {
|
|
126
|
-
return Promise.resolve();
|
|
132
|
+
public getCheckpointAttestationsForSlot(_slot: SlotNumber, _proposalId?: string): Promise<CheckpointAttestation[]> {
|
|
133
|
+
throw new Error('DummyP2P does not implement "getCheckpointAttestationsForSlot"');
|
|
127
134
|
}
|
|
128
135
|
|
|
129
|
-
public
|
|
130
|
-
throw new Error('DummyP2P does not implement "
|
|
136
|
+
public addCheckpointAttestations(_attestations: CheckpointAttestation[]): Promise<void> {
|
|
137
|
+
throw new Error('DummyP2P does not implement "addCheckpointAttestations"');
|
|
131
138
|
}
|
|
132
139
|
|
|
133
140
|
public getL2BlockHash(_number: number): Promise<string | undefined> {
|
|
@@ -3,10 +3,10 @@ import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
3
3
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
4
|
import { GasFees } from '@aztec/stdlib/gas';
|
|
5
5
|
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
6
|
-
import { type GlobalVariableBuilder, GlobalVariables } from '@aztec/stdlib/tx';
|
|
6
|
+
import { type CheckpointGlobalVariables, type GlobalVariableBuilder, GlobalVariables } from '@aztec/stdlib/tx';
|
|
7
7
|
|
|
8
8
|
export class TXEGlobalVariablesBuilder implements GlobalVariableBuilder {
|
|
9
|
-
public
|
|
9
|
+
public getCurrentMinFees(): Promise<GasFees> {
|
|
10
10
|
return Promise.resolve(new GasFees(0, 0));
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -18,4 +18,21 @@ export class TXEGlobalVariablesBuilder implements GlobalVariableBuilder {
|
|
|
18
18
|
): Promise<GlobalVariables> {
|
|
19
19
|
return Promise.resolve(makeGlobalVariables());
|
|
20
20
|
}
|
|
21
|
+
|
|
22
|
+
public buildCheckpointGlobalVariables(
|
|
23
|
+
_coinbase: EthAddress,
|
|
24
|
+
_feeRecipient: AztecAddress,
|
|
25
|
+
_slotNumber: SlotNumber,
|
|
26
|
+
): Promise<CheckpointGlobalVariables> {
|
|
27
|
+
const vars = makeGlobalVariables();
|
|
28
|
+
return Promise.resolve({
|
|
29
|
+
chainId: vars.chainId,
|
|
30
|
+
version: vars.version,
|
|
31
|
+
slotNumber: vars.slotNumber,
|
|
32
|
+
timestamp: vars.timestamp,
|
|
33
|
+
coinbase: vars.coinbase,
|
|
34
|
+
feeRecipient: vars.feeRecipient,
|
|
35
|
+
gasFees: vars.gasFees,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
21
38
|
}
|