@aztec/txe 0.0.1-commit.c7c42ec → 0.0.1-commit.c80b6263
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/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 +4 -2
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +44 -28
- package/dest/rpc_translator.d.ts +16 -10
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +52 -39
- 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 +57 -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 +1 -1
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +22 -4
- 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 +6 -4
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +55 -20
- 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 +16 -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/constants.ts +3 -0
- 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 +77 -27
- package/src/rpc_translator.ts +56 -49
- package/src/state_machine/archiver.ts +52 -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 +26 -4
- package/src/state_machine/mock_epoch_cache.ts +10 -11
- package/src/state_machine/synchronizer.ts +2 -2
- package/src/txe_session.ts +88 -16
- package/src/utils/block_creation.ts +17 -16
- package/src/utils/tx_effect_creation.ts +3 -11
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 = BlockHash.fromString(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 = BlockHash.fromString(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
|
|
|
@@ -568,17 +573,14 @@ export class RPCTranslator {
|
|
|
568
573
|
);
|
|
569
574
|
}
|
|
570
575
|
|
|
571
|
-
async utilityGetNullifierMembershipWitness(
|
|
572
|
-
|
|
573
|
-
foreignNullifier: ForeignCallSingle,
|
|
574
|
-
) {
|
|
575
|
-
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
576
|
+
async utilityGetNullifierMembershipWitness(foreignBlockHash: ForeignCallSingle, foreignNullifier: ForeignCallSingle) {
|
|
577
|
+
const blockHash = BlockHash.fromString(foreignBlockHash);
|
|
576
578
|
const nullifier = fromSingle(foreignNullifier);
|
|
577
579
|
|
|
578
|
-
const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(
|
|
580
|
+
const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockHash, nullifier);
|
|
579
581
|
|
|
580
582
|
if (!witness) {
|
|
581
|
-
throw new Error(`Nullifier membership witness not found at block ${
|
|
583
|
+
throw new Error(`Nullifier membership witness not found at block ${blockHash}.`);
|
|
582
584
|
}
|
|
583
585
|
return toForeignCallResult(witness.toNoirRepresentation());
|
|
584
586
|
}
|
|
@@ -639,36 +641,41 @@ export class RPCTranslator {
|
|
|
639
641
|
return toForeignCallResult(header.toFields().map(toSingle));
|
|
640
642
|
}
|
|
641
643
|
|
|
642
|
-
async
|
|
643
|
-
|
|
644
|
-
foreignTreeId: ForeignCallSingle,
|
|
645
|
-
foreignLeafValue: ForeignCallSingle,
|
|
646
|
-
) {
|
|
647
|
-
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
648
|
-
const treeId = fromSingle(foreignTreeId).toNumber();
|
|
644
|
+
async utilityGetNoteHashMembershipWitness(foreignBlockHash: ForeignCallSingle, foreignLeafValue: ForeignCallSingle) {
|
|
645
|
+
const blockHash = BlockHash.fromString(foreignBlockHash);
|
|
649
646
|
const leafValue = fromSingle(foreignLeafValue);
|
|
650
647
|
|
|
651
|
-
const witness = await this.handlerAsUtility().
|
|
648
|
+
const witness = await this.handlerAsUtility().utilityGetNoteHashMembershipWitness(blockHash, leafValue);
|
|
652
649
|
|
|
653
650
|
if (!witness) {
|
|
654
|
-
throw new Error(
|
|
655
|
-
`Membership witness in tree ${MerkleTreeId[treeId]} not found for value ${leafValue} at block ${blockNumber}.`,
|
|
656
|
-
);
|
|
651
|
+
throw new Error(`Note hash ${leafValue} not found in the note hash tree at block ${blockHash.toString()}.`);
|
|
657
652
|
}
|
|
658
|
-
return toForeignCallResult(
|
|
653
|
+
return toForeignCallResult(witness.toNoirRepresentation());
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
async utilityGetArchiveMembershipWitness(foreignBlockHash: ForeignCallSingle, foreignLeafValue: ForeignCallSingle) {
|
|
657
|
+
const blockHash = BlockHash.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());
|
|
659
666
|
}
|
|
660
667
|
|
|
661
668
|
async utilityGetLowNullifierMembershipWitness(
|
|
662
|
-
|
|
669
|
+
foreignBlockHash: ForeignCallSingle,
|
|
663
670
|
foreignNullifier: ForeignCallSingle,
|
|
664
671
|
) {
|
|
665
|
-
const
|
|
672
|
+
const blockHash = BlockHash.fromString(foreignBlockHash);
|
|
666
673
|
const nullifier = fromSingle(foreignNullifier);
|
|
667
674
|
|
|
668
|
-
const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(
|
|
675
|
+
const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockHash, nullifier);
|
|
669
676
|
|
|
670
677
|
if (!witness) {
|
|
671
|
-
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}.`);
|
|
672
679
|
}
|
|
673
680
|
return toForeignCallResult(witness.toNoirRepresentation());
|
|
674
681
|
}
|
|
@@ -681,7 +688,7 @@ export class RPCTranslator {
|
|
|
681
688
|
return toForeignCallResult([]);
|
|
682
689
|
}
|
|
683
690
|
|
|
684
|
-
public async
|
|
691
|
+
public async utilityValidateAndStoreEnqueuedNotesAndEvents(
|
|
685
692
|
foreignContractAddress: ForeignCallSingle,
|
|
686
693
|
foreignNoteValidationRequestsArrayBaseSlot: ForeignCallSingle,
|
|
687
694
|
foreignEventValidationRequestsArrayBaseSlot: ForeignCallSingle,
|
|
@@ -690,7 +697,7 @@ export class RPCTranslator {
|
|
|
690
697
|
const noteValidationRequestsArrayBaseSlot = fromSingle(foreignNoteValidationRequestsArrayBaseSlot);
|
|
691
698
|
const eventValidationRequestsArrayBaseSlot = fromSingle(foreignEventValidationRequestsArrayBaseSlot);
|
|
692
699
|
|
|
693
|
-
await this.handlerAsUtility().
|
|
700
|
+
await this.handlerAsUtility().utilityValidateAndStoreEnqueuedNotesAndEvents(
|
|
694
701
|
contractAddress,
|
|
695
702
|
noteValidationRequestsArrayBaseSlot,
|
|
696
703
|
eventValidationRequestsArrayBaseSlot,
|
|
@@ -828,10 +835,11 @@ export class RPCTranslator {
|
|
|
828
835
|
return toForeignCallResult([]);
|
|
829
836
|
}
|
|
830
837
|
|
|
831
|
-
async avmOpcodeStorageRead(foreignSlot: ForeignCallSingle) {
|
|
838
|
+
async avmOpcodeStorageRead(foreignSlot: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
|
|
832
839
|
const slot = fromSingle(foreignSlot);
|
|
840
|
+
const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
|
|
833
841
|
|
|
834
|
-
const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot)).value;
|
|
842
|
+
const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot, contractAddress)).value;
|
|
835
843
|
|
|
836
844
|
return toForeignCallResult([toSingle(new Fr(value))]);
|
|
837
845
|
}
|
|
@@ -903,11 +911,10 @@ export class RPCTranslator {
|
|
|
903
911
|
return toForeignCallResult([]);
|
|
904
912
|
}
|
|
905
913
|
|
|
906
|
-
async avmOpcodeNullifierExists(
|
|
907
|
-
const
|
|
908
|
-
const targetAddress = AztecAddress.fromField(fromSingle(foreignTargetAddress));
|
|
914
|
+
async avmOpcodeNullifierExists(foreignSiloedNullifier: ForeignCallSingle) {
|
|
915
|
+
const siloedNullifier = fromSingle(foreignSiloedNullifier);
|
|
909
916
|
|
|
910
|
-
const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(
|
|
917
|
+
const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(siloedNullifier);
|
|
911
918
|
|
|
912
919
|
return toForeignCallResult([toSingle(new Fr(exists))]);
|
|
913
920
|
}
|
|
@@ -1,204 +1,48 @@
|
|
|
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
|
-
import { isDefined } from '@aztec/foundation/types';
|
|
7
6
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
8
|
-
import type {
|
|
9
|
-
import {
|
|
10
|
-
CommitteeAttestation,
|
|
11
|
-
L2Block,
|
|
12
|
-
type L2BlockId,
|
|
13
|
-
type L2BlockNew,
|
|
14
|
-
type L2BlockSource,
|
|
15
|
-
type L2Tips,
|
|
16
|
-
PublishedL2Block,
|
|
17
|
-
type ValidateBlockResult,
|
|
18
|
-
} from '@aztec/stdlib/block';
|
|
19
|
-
import { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
20
|
-
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';
|
|
21
9
|
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
22
|
-
import type { BlockHeader } from '@aztec/stdlib/tx';
|
|
23
|
-
import type { UInt64 } from '@aztec/stdlib/types';
|
|
24
10
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
public async getBlock(number: BlockNumber): Promise<L2Block | undefined> {
|
|
34
|
-
if (number === 0) {
|
|
35
|
-
return undefined;
|
|
36
|
-
}
|
|
37
|
-
const publishedBlocks = await this.getPublishedBlocks(number, 1);
|
|
38
|
-
if (publishedBlocks.length === 0) {
|
|
39
|
-
return undefined;
|
|
40
|
-
}
|
|
41
|
-
return publishedBlocks[0].block;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
public async getBlocks(from: BlockNumber, limit: number, proven?: boolean): Promise<L2Block[]> {
|
|
45
|
-
const publishedBlocks = await this.getPublishedBlocks(from, limit, proven);
|
|
46
|
-
return publishedBlocks.map(x => x.block);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
public override async addCheckpoints(
|
|
50
|
-
checkpoints: PublishedCheckpoint[],
|
|
51
|
-
_result?: ValidateBlockResult,
|
|
52
|
-
): Promise<boolean> {
|
|
53
|
-
const allBlocks = checkpoints.flatMap(ch => ch.checkpoint.blocks);
|
|
54
|
-
const opResults = await Promise.all([this.store.addLogs(allBlocks), this.store.addCheckpoints(checkpoints)]);
|
|
55
|
-
|
|
56
|
-
return opResults.every(Boolean);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Gets the number of the latest L2 block processed by the block source implementation.
|
|
61
|
-
* @returns The number of the latest L2 block processed by the block source implementation.
|
|
62
|
-
*/
|
|
63
|
-
public getBlockNumber(): Promise<BlockNumber> {
|
|
64
|
-
return this.store.getLatestBlockNumber();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Gets the number of the latest L2 block proven seen by the block source implementation.
|
|
69
|
-
* @returns The number of the latest L2 block proven seen by the block source implementation.
|
|
70
|
-
*/
|
|
71
|
-
public override getProvenBlockNumber(): Promise<BlockNumber> {
|
|
72
|
-
return this.store.getProvenBlockNumber();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Gets a published l2 block. If a negative number is passed, the block returned is the most recent.
|
|
77
|
-
* @param number - The block number to return (inclusive).
|
|
78
|
-
* @returns The requested L2 block.
|
|
79
|
-
*/
|
|
80
|
-
public async getPublishedBlock(number: number): Promise<PublishedL2Block | undefined> {
|
|
81
|
-
// If the number provided is -ve, then return the latest block.
|
|
82
|
-
if (number < 0) {
|
|
83
|
-
number = await this.store.getLatestBlockNumber();
|
|
84
|
-
}
|
|
85
|
-
if (number == 0) {
|
|
86
|
-
return undefined;
|
|
87
|
-
}
|
|
88
|
-
const publishedBlocks = await this.retrievePublishedBlocks(BlockNumber(number), 1);
|
|
89
|
-
return publishedBlocks.length === 0 ? undefined : publishedBlocks[0];
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
getPublishedBlocks(from: BlockNumber, limit: number, proven?: boolean): Promise<PublishedL2Block[]> {
|
|
93
|
-
return this.retrievePublishedBlocks(from, limit, proven);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
private async retrievePublishedBlocks(
|
|
97
|
-
from: BlockNumber,
|
|
98
|
-
limit: number,
|
|
99
|
-
proven?: boolean,
|
|
100
|
-
): Promise<PublishedL2Block[]> {
|
|
101
|
-
const checkpoints = await this.store.getRangeOfCheckpoints(CheckpointNumber(from), limit);
|
|
102
|
-
const provenCheckpointNumber = await this.store.getProvenCheckpointNumber();
|
|
103
|
-
const blocks = (
|
|
104
|
-
await Promise.all(checkpoints.map(ch => this.store.getBlocksForCheckpoint(ch.checkpointNumber)))
|
|
105
|
-
).filter(isDefined);
|
|
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);
|
|
106
18
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const checkpoint = checkpoints[i];
|
|
111
|
-
if (proven === true && checkpoint.checkpointNumber > provenCheckpointNumber) {
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
const oldCheckpoint = new Checkpoint(
|
|
115
|
-
blockForCheckpoint.archive,
|
|
116
|
-
checkpoint.header,
|
|
117
|
-
[blockForCheckpoint],
|
|
118
|
-
checkpoint.checkpointNumber,
|
|
119
|
-
);
|
|
120
|
-
const oldBlock = L2Block.fromCheckpoint(oldCheckpoint);
|
|
121
|
-
const publishedBlock = new PublishedL2Block(
|
|
122
|
-
oldBlock,
|
|
123
|
-
checkpoint.l1,
|
|
124
|
-
checkpoint.attestations.map(x => CommitteeAttestation.fromBuffer(x)),
|
|
125
|
-
);
|
|
126
|
-
olbBlocks.push(publishedBlock);
|
|
127
|
-
}
|
|
128
|
-
return olbBlocks;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Gets an l2 block. If a negative number is passed, the block returned is the most recent.
|
|
133
|
-
* @param number - The block number to return (inclusive).
|
|
134
|
-
* @returns The requested L2 block.
|
|
135
|
-
*/
|
|
136
|
-
public getL2Block(number: BlockNumber | 'latest'): Promise<L2Block | undefined> {
|
|
137
|
-
return this.getPublishedBlock(number != 'latest' ? number : -1).then(b => b?.block);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Gets an L2 block (new format).
|
|
142
|
-
* @param number - The block number to return.
|
|
143
|
-
* @returns The requested L2 block.
|
|
144
|
-
*/
|
|
145
|
-
public getL2BlockNew(number: BlockNumber): Promise<L2BlockNew | undefined> {
|
|
146
|
-
if (number === 0) {
|
|
147
|
-
return Promise.resolve(undefined);
|
|
148
|
-
}
|
|
149
|
-
return this.store.getBlock(number);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Gets an l2 block header.
|
|
154
|
-
* @param number - The block number to return or 'latest' for the most recent one.
|
|
155
|
-
* @returns The requested L2 block header.
|
|
156
|
-
*/
|
|
157
|
-
public async getBlockHeader(number: number | 'latest'): Promise<BlockHeader | undefined> {
|
|
158
|
-
if (number === 'latest') {
|
|
159
|
-
number = await this.store.getLatestBlockNumber();
|
|
160
|
-
}
|
|
161
|
-
if (number === 0) {
|
|
162
|
-
return undefined;
|
|
163
|
-
}
|
|
164
|
-
const headers = await this.store.getBlockHeaders(BlockNumber(number), 1);
|
|
165
|
-
return headers.length === 0 ? undefined : headers[0];
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
public getBlockRange(from: number, limit: number, _proven?: boolean): Promise<L2Block[]> {
|
|
169
|
-
return this.getPublishedBlocks(BlockNumber(from), limit).then(blocks => blocks.map(b => b.block));
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
public getPublishedCheckpoints(_from: CheckpointNumber, _limit: number): Promise<PublishedCheckpoint[]> {
|
|
173
|
-
throw new Error('TXE Archiver does not implement "getPublishedCheckpoints"');
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
public getCheckpointByArchive(_archive: Fr): Promise<Checkpoint | undefined> {
|
|
177
|
-
throw new Error('TXE Archiver does not implement "getCheckpointByArchive"');
|
|
19
|
+
constructor(db: AztecAsyncKVStore) {
|
|
20
|
+
const store = new KVArchiverDataStore(db, 9999, { epochDuration: 32 });
|
|
21
|
+
super(store);
|
|
178
22
|
}
|
|
179
23
|
|
|
180
|
-
public
|
|
181
|
-
|
|
24
|
+
public async addCheckpoints(checkpoints: PublishedCheckpoint[], result?: ValidateCheckpointResult): Promise<void> {
|
|
25
|
+
await this.updater.addCheckpoints(checkpoints, result);
|
|
182
26
|
}
|
|
183
27
|
|
|
184
|
-
public
|
|
185
|
-
throw new Error('TXE Archiver does not implement "
|
|
28
|
+
public getRollupAddress(): Promise<EthAddress> {
|
|
29
|
+
throw new Error('TXE Archiver does not implement "getRollupAddress"');
|
|
186
30
|
}
|
|
187
31
|
|
|
188
|
-
public
|
|
189
|
-
throw new Error('TXE Archiver does not implement "
|
|
32
|
+
public getRegistryAddress(): Promise<EthAddress> {
|
|
33
|
+
throw new Error('TXE Archiver does not implement "getRegistryAddress"');
|
|
190
34
|
}
|
|
191
35
|
|
|
192
|
-
public
|
|
193
|
-
throw new Error('TXE Archiver does not implement "
|
|
36
|
+
public getL1Constants(): Promise<L1RollupConstants> {
|
|
37
|
+
throw new Error('TXE Archiver does not implement "getL1Constants"');
|
|
194
38
|
}
|
|
195
39
|
|
|
196
|
-
public
|
|
197
|
-
|
|
40
|
+
public getGenesisValues(): Promise<{ genesisArchiveRoot: Fr }> {
|
|
41
|
+
return Promise.resolve({ genesisArchiveRoot: new Fr(GENESIS_ARCHIVE_ROOT) });
|
|
198
42
|
}
|
|
199
43
|
|
|
200
|
-
public
|
|
201
|
-
throw new Error('TXE Archiver does not implement "
|
|
44
|
+
public getL1Timestamp(): Promise<bigint | undefined> {
|
|
45
|
+
throw new Error('TXE Archiver does not implement "getL1Timestamp"');
|
|
202
46
|
}
|
|
203
47
|
|
|
204
48
|
public async getL2Tips(): Promise<L2Tips> {
|
|
@@ -211,53 +55,41 @@ export class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
|
|
|
211
55
|
|
|
212
56
|
const number = blockHeader.globalVariables.blockNumber;
|
|
213
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 };
|
|
214
72
|
return {
|
|
215
|
-
|
|
216
|
-
proven:
|
|
217
|
-
finalized:
|
|
73
|
+
proposed: blockId,
|
|
74
|
+
proven: tipId,
|
|
75
|
+
finalized: tipId,
|
|
76
|
+
checkpointed: tipId,
|
|
218
77
|
};
|
|
219
78
|
}
|
|
220
79
|
|
|
221
|
-
public
|
|
222
|
-
throw new Error('TXE Archiver does not implement "
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
public getGenesisValues(): Promise<{ genesisArchiveRoot: Fr }> {
|
|
226
|
-
return Promise.resolve({ genesisArchiveRoot: new Fr(GENESIS_ARCHIVE_ROOT) });
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
public syncImmediate(): Promise<void> {
|
|
230
|
-
throw new Error('TXE Archiver does not implement "syncImmediate"');
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
public getContract(_address: AztecAddress, _timestamp?: UInt64): Promise<ContractInstanceWithAddress | undefined> {
|
|
234
|
-
throw new Error('TXE Archiver does not implement "getContract"');
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
public getRollupAddress(): Promise<EthAddress> {
|
|
238
|
-
throw new Error('TXE Archiver does not implement "getRollupAddress"');
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
public getRegistryAddress(): Promise<EthAddress> {
|
|
242
|
-
throw new Error('TXE Archiver does not implement "getRegistryAddress"');
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
public getL1Timestamp(): Promise<bigint> {
|
|
246
|
-
throw new Error('TXE Archiver does not implement "getL1Timestamp"');
|
|
80
|
+
public getL2SlotNumber(): Promise<SlotNumber | undefined> {
|
|
81
|
+
throw new Error('TXE Archiver does not implement "getL2SlotNumber"');
|
|
247
82
|
}
|
|
248
83
|
|
|
249
|
-
public
|
|
250
|
-
|
|
84
|
+
public getL2EpochNumber(): Promise<EpochNumber | undefined> {
|
|
85
|
+
throw new Error('TXE Archiver does not implement "getL2EpochNumber"');
|
|
251
86
|
}
|
|
252
87
|
|
|
253
|
-
public
|
|
254
|
-
|
|
88
|
+
public isEpochComplete(_epochNumber: EpochNumber): Promise<boolean> {
|
|
89
|
+
throw new Error('TXE Archiver does not implement "isEpochComplete"');
|
|
255
90
|
}
|
|
256
91
|
|
|
257
|
-
|
|
258
|
-
throw new Error('
|
|
259
|
-
}
|
|
260
|
-
getPublishedBlockByArchive(_archive: Fr): Promise<PublishedL2Block | undefined> {
|
|
261
|
-
throw new Error('Method not implemented.');
|
|
92
|
+
public syncImmediate(): Promise<void> {
|
|
93
|
+
throw new Error('TXE Archiver does not implement "syncImmediate"');
|
|
262
94
|
}
|
|
263
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
|
}
|
|
@@ -120,16 +129,12 @@ export class DummyP2P implements P2P {
|
|
|
120
129
|
throw new Error('DummyP2P does not implement "getTxsByHash"');
|
|
121
130
|
}
|
|
122
131
|
|
|
123
|
-
public
|
|
124
|
-
throw new Error('DummyP2P does not implement "
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
public deleteAttestation(_attestation: BlockAttestation): Promise<void> {
|
|
128
|
-
return Promise.resolve();
|
|
132
|
+
public getCheckpointAttestationsForSlot(_slot: SlotNumber, _proposalId?: string): Promise<CheckpointAttestation[]> {
|
|
133
|
+
throw new Error('DummyP2P does not implement "getCheckpointAttestationsForSlot"');
|
|
129
134
|
}
|
|
130
135
|
|
|
131
|
-
public
|
|
132
|
-
throw new Error('DummyP2P does not implement "
|
|
136
|
+
public addCheckpointAttestations(_attestations: CheckpointAttestation[]): Promise<void> {
|
|
137
|
+
throw new Error('DummyP2P does not implement "addCheckpointAttestations"');
|
|
133
138
|
}
|
|
134
139
|
|
|
135
140
|
public getL2BlockHash(_number: number): Promise<string | undefined> {
|
|
@@ -6,7 +6,7 @@ import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
|
6
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
|
|