@aztec/aztec-node 0.0.1-commit.1142ef1 → 0.0.1-commit.18ccd8f0
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/aztec-node/node_metrics.d.ts +1 -1
- package/dest/aztec-node/node_metrics.d.ts.map +1 -1
- package/dest/aztec-node/node_metrics.js +8 -4
- package/dest/aztec-node/server.d.ts +26 -90
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +159 -149
- package/dest/sentinel/factory.d.ts +1 -1
- package/dest/sentinel/factory.d.ts.map +1 -1
- package/dest/sentinel/factory.js +1 -1
- package/dest/sentinel/sentinel.js +1 -1
- package/dest/sentinel/store.d.ts +2 -2
- package/dest/sentinel/store.d.ts.map +1 -1
- package/package.json +26 -25
- package/src/aztec-node/node_metrics.ts +12 -5
- package/src/aztec-node/server.ts +198 -186
- package/src/sentinel/factory.ts +1 -6
- package/src/sentinel/sentinel.ts +1 -1
package/src/aztec-node/server.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { BBCircuitVerifier, QueuedIVCVerifier, TestCircuitVerifier } from '@azte
|
|
|
3
3
|
import { type BlobClientInterface, createBlobClientWithFileStores } from '@aztec/blob-client/client';
|
|
4
4
|
import {
|
|
5
5
|
ARCHIVE_HEIGHT,
|
|
6
|
-
INITIAL_L2_BLOCK_NUM,
|
|
7
6
|
type L1_TO_L2_MSG_TREE_HEIGHT,
|
|
8
7
|
type NOTE_HASH_TREE_HEIGHT,
|
|
9
8
|
type NULLIFIER_TREE_HEIGHT,
|
|
@@ -31,7 +30,7 @@ import {
|
|
|
31
30
|
} from '@aztec/node-lib/factories';
|
|
32
31
|
import { type P2P, type P2PClientDeps, createP2PClient, getDefaultAllowedSetupFunctions } from '@aztec/p2p';
|
|
33
32
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
34
|
-
import {
|
|
33
|
+
import { GlobalVariableBuilder, SequencerClient, type SequencerPublisher } from '@aztec/sequencer-client';
|
|
35
34
|
import { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
36
35
|
import {
|
|
37
36
|
AttestationsBlockWatcher,
|
|
@@ -42,15 +41,7 @@ import {
|
|
|
42
41
|
} from '@aztec/slasher';
|
|
43
42
|
import { CollectionLimitsConfig, PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
44
43
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
45
|
-
import {
|
|
46
|
-
type BlockParameter,
|
|
47
|
-
type DataInBlock,
|
|
48
|
-
type L2Block,
|
|
49
|
-
L2BlockHash,
|
|
50
|
-
L2BlockNew,
|
|
51
|
-
type L2BlockSource,
|
|
52
|
-
type PublishedL2Block,
|
|
53
|
-
} from '@aztec/stdlib/block';
|
|
44
|
+
import { BlockHash, type BlockParameter, type DataInBlock, L2Block, type L2BlockSource } from '@aztec/stdlib/block';
|
|
54
45
|
import type { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
55
46
|
import type {
|
|
56
47
|
ContractClassPublic,
|
|
@@ -128,6 +119,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
128
119
|
*/
|
|
129
120
|
export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
130
121
|
private metrics: NodeMetrics;
|
|
122
|
+
private initialHeaderHashPromise: Promise<BlockHash> | undefined = undefined;
|
|
131
123
|
|
|
132
124
|
// Prevent two snapshot operations to happen simultaneously
|
|
133
125
|
private isUploadingSnapshot = false;
|
|
@@ -309,18 +301,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
309
301
|
// We should really not be modifying the config object
|
|
310
302
|
config.txPublicSetupAllowList = config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
|
|
311
303
|
|
|
312
|
-
// Create BlockBuilder for EpochPruneWatcher (slasher functionality)
|
|
313
|
-
const blockBuilder = new BlockBuilder(
|
|
314
|
-
{ ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
|
|
315
|
-
worldStateSynchronizer,
|
|
316
|
-
archiver,
|
|
317
|
-
dateProvider,
|
|
318
|
-
telemetry,
|
|
319
|
-
);
|
|
320
|
-
|
|
321
304
|
// Create FullNodeCheckpointsBuilder for validator and non-validator block proposal handling
|
|
322
305
|
const validatorCheckpointsBuilder = new FullNodeCheckpointsBuilder(
|
|
323
306
|
{ ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
|
|
307
|
+
worldStateSynchronizer,
|
|
324
308
|
archiver,
|
|
325
309
|
dateProvider,
|
|
326
310
|
telemetry,
|
|
@@ -330,7 +314,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
330
314
|
const watchers: Watcher[] = [];
|
|
331
315
|
|
|
332
316
|
// Create validator client if required
|
|
333
|
-
const validatorClient = createValidatorClient(config, {
|
|
317
|
+
const validatorClient = await createValidatorClient(config, {
|
|
334
318
|
checkpointsBuilder: validatorCheckpointsBuilder,
|
|
335
319
|
worldState: worldStateSynchronizer,
|
|
336
320
|
p2pClient,
|
|
@@ -387,7 +371,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
387
371
|
archiver,
|
|
388
372
|
epochCache,
|
|
389
373
|
p2pClient.getTxProvider(),
|
|
390
|
-
|
|
374
|
+
validatorCheckpointsBuilder,
|
|
391
375
|
config,
|
|
392
376
|
);
|
|
393
377
|
watchers.push(epochPruneWatcher);
|
|
@@ -452,6 +436,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
452
436
|
// Create and start the sequencer client
|
|
453
437
|
const checkpointsBuilder = new CheckpointsBuilder(
|
|
454
438
|
{ ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
|
|
439
|
+
worldStateSynchronizer,
|
|
455
440
|
archiver,
|
|
456
441
|
dateProvider,
|
|
457
442
|
telemetry,
|
|
@@ -580,13 +565,19 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
580
565
|
}
|
|
581
566
|
|
|
582
567
|
/**
|
|
583
|
-
* Get a block specified by its number.
|
|
584
|
-
* @param
|
|
568
|
+
* Get a block specified by its block number, block hash, or 'latest'.
|
|
569
|
+
* @param block - The block parameter (block number, block hash, or 'latest').
|
|
585
570
|
* @returns The requested block.
|
|
586
571
|
*/
|
|
587
|
-
public async getBlock(
|
|
588
|
-
|
|
589
|
-
|
|
572
|
+
public async getBlock(block: BlockParameter): Promise<L2Block | undefined> {
|
|
573
|
+
if (BlockHash.isL2BlockHash(block)) {
|
|
574
|
+
return this.getBlockByHash(Fr.fromBuffer(block.toBuffer()));
|
|
575
|
+
}
|
|
576
|
+
const blockNumber = block === 'latest' ? await this.getBlockNumber() : (block as BlockNumber);
|
|
577
|
+
if (blockNumber === BlockNumber.ZERO) {
|
|
578
|
+
return this.buildInitialBlock();
|
|
579
|
+
}
|
|
580
|
+
return await this.blockSource.getL2Block(blockNumber);
|
|
590
581
|
}
|
|
591
582
|
|
|
592
583
|
/**
|
|
@@ -595,8 +586,16 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
595
586
|
* @returns The requested block.
|
|
596
587
|
*/
|
|
597
588
|
public async getBlockByHash(blockHash: Fr): Promise<L2Block | undefined> {
|
|
598
|
-
const
|
|
599
|
-
|
|
589
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
590
|
+
if (blockHash.equals(Fr.fromBuffer(initialBlockHash.toBuffer()))) {
|
|
591
|
+
return this.buildInitialBlock();
|
|
592
|
+
}
|
|
593
|
+
return await this.blockSource.getL2BlockByHash(blockHash);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
private buildInitialBlock(): L2Block {
|
|
597
|
+
const initialHeader = this.worldStateSynchronizer.getCommitted().getInitialHeader();
|
|
598
|
+
return L2Block.empty(initialHeader);
|
|
600
599
|
}
|
|
601
600
|
|
|
602
601
|
/**
|
|
@@ -605,8 +604,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
605
604
|
* @returns The requested block.
|
|
606
605
|
*/
|
|
607
606
|
public async getBlockByArchive(archive: Fr): Promise<L2Block | undefined> {
|
|
608
|
-
|
|
609
|
-
return publishedBlock?.block;
|
|
607
|
+
return await this.blockSource.getL2BlockByArchive(archive);
|
|
610
608
|
}
|
|
611
609
|
|
|
612
610
|
/**
|
|
@@ -616,23 +614,15 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
616
614
|
* @returns The blocks requested.
|
|
617
615
|
*/
|
|
618
616
|
public async getBlocks(from: BlockNumber, limit: number): Promise<L2Block[]> {
|
|
619
|
-
return (await this.blockSource.getBlocks(from, limit)) ?? [];
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
public async getPublishedBlocks(from: BlockNumber, limit: number): Promise<PublishedL2Block[]> {
|
|
623
|
-
return (await this.blockSource.getPublishedBlocks(from, limit)) ?? [];
|
|
617
|
+
return (await this.blockSource.getBlocks(from, BlockNumber(limit))) ?? [];
|
|
624
618
|
}
|
|
625
619
|
|
|
626
|
-
public async
|
|
627
|
-
return (await this.blockSource.
|
|
620
|
+
public async getCheckpoints(from: CheckpointNumber, limit: number): Promise<PublishedCheckpoint[]> {
|
|
621
|
+
return (await this.blockSource.getCheckpoints(from, limit)) ?? [];
|
|
628
622
|
}
|
|
629
623
|
|
|
630
|
-
public async
|
|
631
|
-
return (await this.blockSource.
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
public async getCheckpointedBlocks(from: BlockNumber, limit: number, proven?: boolean) {
|
|
635
|
-
return (await this.blockSource.getCheckpointedBlocks(from, limit, proven)) ?? [];
|
|
624
|
+
public async getCheckpointedBlocks(from: BlockNumber, limit: number) {
|
|
625
|
+
return (await this.blockSource.getCheckpointedBlocks(from, limit)) ?? [];
|
|
636
626
|
}
|
|
637
627
|
|
|
638
628
|
/**
|
|
@@ -663,6 +653,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
663
653
|
return await this.blockSource.getProvenBlockNumber();
|
|
664
654
|
}
|
|
665
655
|
|
|
656
|
+
public async getCheckpointedBlockNumber(): Promise<BlockNumber> {
|
|
657
|
+
return await this.blockSource.getCheckpointedL2BlockNumber();
|
|
658
|
+
}
|
|
659
|
+
|
|
666
660
|
/**
|
|
667
661
|
* Method to fetch the version of the package.
|
|
668
662
|
* @returns The node package version
|
|
@@ -695,12 +689,45 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
695
689
|
return this.contractDataSource.getContract(address);
|
|
696
690
|
}
|
|
697
691
|
|
|
698
|
-
public getPrivateLogsByTags(
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
692
|
+
public async getPrivateLogsByTags(
|
|
693
|
+
tags: SiloedTag[],
|
|
694
|
+
page?: number,
|
|
695
|
+
referenceBlock?: BlockHash,
|
|
696
|
+
): Promise<TxScopedL2Log[][]> {
|
|
697
|
+
if (referenceBlock) {
|
|
698
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
699
|
+
if (!referenceBlock.equals(initialBlockHash)) {
|
|
700
|
+
const blockHashFr = Fr.fromBuffer(referenceBlock.toBuffer());
|
|
701
|
+
const header = await this.blockSource.getBlockHeaderByHash(blockHashFr);
|
|
702
|
+
if (!header) {
|
|
703
|
+
throw new Error(
|
|
704
|
+
`Block ${referenceBlock.toString()} not found in the node. This might indicate a reorg has occurred.`,
|
|
705
|
+
);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return this.logsSource.getPrivateLogsByTags(tags, page);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
public async getPublicLogsByTagsFromContract(
|
|
713
|
+
contractAddress: AztecAddress,
|
|
714
|
+
tags: Tag[],
|
|
715
|
+
page?: number,
|
|
716
|
+
referenceBlock?: BlockHash,
|
|
717
|
+
): Promise<TxScopedL2Log[][]> {
|
|
718
|
+
if (referenceBlock) {
|
|
719
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
720
|
+
if (!referenceBlock.equals(initialBlockHash)) {
|
|
721
|
+
const blockHashFr = Fr.fromBuffer(referenceBlock.toBuffer());
|
|
722
|
+
const header = await this.blockSource.getBlockHeaderByHash(blockHashFr);
|
|
723
|
+
if (!header) {
|
|
724
|
+
throw new Error(
|
|
725
|
+
`Block ${referenceBlock.toString()} not found in the node. This might indicate a reorg has occurred.`,
|
|
726
|
+
);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
return this.logsSource.getPublicLogsByTagsFromContract(contractAddress, tags, page);
|
|
704
731
|
}
|
|
705
732
|
|
|
706
733
|
/**
|
|
@@ -747,21 +774,26 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
747
774
|
}
|
|
748
775
|
|
|
749
776
|
public async getTxReceipt(txHash: TxHash): Promise<TxReceipt> {
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
// and we would incorrectly return a TxReceipt with status DROPPED
|
|
755
|
-
if ((await this.p2pClient.getTxStatus(txHash)) === 'pending') {
|
|
756
|
-
txReceipt = new TxReceipt(txHash, TxStatus.PENDING, '');
|
|
757
|
-
}
|
|
777
|
+
// Check the tx pool status first. If the tx is known to the pool (pending or mined), we'll use that
|
|
778
|
+
// as a fallback if we don't find a settled receipt in the archiver.
|
|
779
|
+
const txPoolStatus = await this.p2pClient.getTxStatus(txHash);
|
|
780
|
+
const isKnownToPool = txPoolStatus === 'pending' || txPoolStatus === 'mined';
|
|
758
781
|
|
|
782
|
+
// Then get the actual tx from the archiver, which tracks every tx in a mined block.
|
|
759
783
|
const settledTxReceipt = await this.blockSource.getSettledTxReceipt(txHash);
|
|
784
|
+
|
|
760
785
|
if (settledTxReceipt) {
|
|
761
|
-
|
|
786
|
+
// If the archiver has the receipt then return it.
|
|
787
|
+
return settledTxReceipt;
|
|
788
|
+
} else if (isKnownToPool) {
|
|
789
|
+
// If the tx is in the pool but not in the archiver, it's pending.
|
|
790
|
+
// This handles race conditions between archiver and p2p, where the archiver
|
|
791
|
+
// has pruned the block in which a tx was mined, but p2p has not caught up yet.
|
|
792
|
+
return new TxReceipt(txHash, TxStatus.PENDING, undefined, undefined);
|
|
793
|
+
} else {
|
|
794
|
+
// Otherwise, if we don't know the tx, we consider it dropped.
|
|
795
|
+
return new TxReceipt(txHash, TxStatus.DROPPED, undefined, 'Tx dropped by P2P node');
|
|
762
796
|
}
|
|
763
|
-
|
|
764
|
-
return txReceipt;
|
|
765
797
|
}
|
|
766
798
|
|
|
767
799
|
public getTxEffect(txHash: TxHash): Promise<IndexedTxEffect | undefined> {
|
|
@@ -826,20 +858,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
826
858
|
return compactArray(await Promise.all(txHashes.map(txHash => this.getTxByHash(txHash))));
|
|
827
859
|
}
|
|
828
860
|
|
|
829
|
-
/**
|
|
830
|
-
* Find the indexes of the given leaves in the given tree along with a block metadata pointing to the block in which
|
|
831
|
-
* the leaves were inserted.
|
|
832
|
-
* @param blockNumber - The block number at which to get the data or 'latest' for latest data.
|
|
833
|
-
* @param treeId - The tree to search in.
|
|
834
|
-
* @param leafValues - The values to search for.
|
|
835
|
-
* @returns The indices of leaves and the block metadata of a block in which the leaves were inserted.
|
|
836
|
-
*/
|
|
837
861
|
public async findLeavesIndexes(
|
|
838
|
-
|
|
862
|
+
block: BlockParameter,
|
|
839
863
|
treeId: MerkleTreeId,
|
|
840
864
|
leafValues: Fr[],
|
|
841
865
|
): Promise<(DataInBlock<bigint> | undefined)[]> {
|
|
842
|
-
const committedDb = await this.#getWorldState(
|
|
866
|
+
const committedDb = await this.#getWorldState(block);
|
|
843
867
|
const maybeIndices = await committedDb.findLeafIndices(
|
|
844
868
|
treeId,
|
|
845
869
|
leafValues.map(x => x.toBuffer()),
|
|
@@ -891,45 +915,33 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
891
915
|
}
|
|
892
916
|
return {
|
|
893
917
|
l2BlockNumber: BlockNumber(Number(blockNumber)),
|
|
894
|
-
l2BlockHash:
|
|
918
|
+
l2BlockHash: BlockHash.fromField(blockHash),
|
|
895
919
|
data: index,
|
|
896
920
|
};
|
|
897
921
|
});
|
|
898
922
|
}
|
|
899
923
|
|
|
900
|
-
/**
|
|
901
|
-
* Returns a sibling path for the given index in the nullifier tree.
|
|
902
|
-
* @param blockNumber - The block number at which to get the data.
|
|
903
|
-
* @param leafIndex - The index of the leaf for which the sibling path is required.
|
|
904
|
-
* @returns The sibling path for the leaf index.
|
|
905
|
-
*/
|
|
906
924
|
public async getNullifierSiblingPath(
|
|
907
|
-
|
|
925
|
+
block: BlockParameter,
|
|
908
926
|
leafIndex: bigint,
|
|
909
927
|
): Promise<SiblingPath<typeof NULLIFIER_TREE_HEIGHT>> {
|
|
910
|
-
const committedDb = await this.#getWorldState(
|
|
928
|
+
const committedDb = await this.#getWorldState(block);
|
|
911
929
|
return committedDb.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, leafIndex);
|
|
912
930
|
}
|
|
913
931
|
|
|
914
|
-
/**
|
|
915
|
-
* Returns a sibling path for the given index in the data tree.
|
|
916
|
-
* @param blockNumber - The block number at which to get the data.
|
|
917
|
-
* @param leafIndex - The index of the leaf for which the sibling path is required.
|
|
918
|
-
* @returns The sibling path for the leaf index.
|
|
919
|
-
*/
|
|
920
932
|
public async getNoteHashSiblingPath(
|
|
921
|
-
|
|
933
|
+
block: BlockParameter,
|
|
922
934
|
leafIndex: bigint,
|
|
923
935
|
): Promise<SiblingPath<typeof NOTE_HASH_TREE_HEIGHT>> {
|
|
924
|
-
const committedDb = await this.#getWorldState(
|
|
936
|
+
const committedDb = await this.#getWorldState(block);
|
|
925
937
|
return committedDb.getSiblingPath(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
|
|
926
938
|
}
|
|
927
939
|
|
|
928
940
|
public async getArchiveMembershipWitness(
|
|
929
|
-
|
|
941
|
+
block: BlockParameter,
|
|
930
942
|
archive: Fr,
|
|
931
943
|
): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined> {
|
|
932
|
-
const committedDb = await this.#getWorldState(
|
|
944
|
+
const committedDb = await this.#getWorldState(block);
|
|
933
945
|
const [pathAndIndex] = await committedDb.findSiblingPaths<MerkleTreeId.ARCHIVE>(MerkleTreeId.ARCHIVE, [archive]);
|
|
934
946
|
return pathAndIndex === undefined
|
|
935
947
|
? undefined
|
|
@@ -937,10 +949,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
937
949
|
}
|
|
938
950
|
|
|
939
951
|
public async getNoteHashMembershipWitness(
|
|
940
|
-
|
|
952
|
+
block: BlockParameter,
|
|
941
953
|
noteHash: Fr,
|
|
942
954
|
): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
|
|
943
|
-
const committedDb = await this.#getWorldState(
|
|
955
|
+
const committedDb = await this.#getWorldState(block);
|
|
944
956
|
const [pathAndIndex] = await committedDb.findSiblingPaths<MerkleTreeId.NOTE_HASH_TREE>(
|
|
945
957
|
MerkleTreeId.NOTE_HASH_TREE,
|
|
946
958
|
[noteHash],
|
|
@@ -950,17 +962,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
950
962
|
: MembershipWitness.fromSiblingPath(pathAndIndex.index, pathAndIndex.path);
|
|
951
963
|
}
|
|
952
964
|
|
|
953
|
-
/**
|
|
954
|
-
* Returns the index and a sibling path for a leaf in the committed l1 to l2 data tree.
|
|
955
|
-
* @param blockNumber - The block number at which to get the data.
|
|
956
|
-
* @param l1ToL2Message - The l1ToL2Message to get the index / sibling path for.
|
|
957
|
-
* @returns A tuple of the index and the sibling path of the L1ToL2Message (undefined if not found).
|
|
958
|
-
*/
|
|
959
965
|
public async getL1ToL2MessageMembershipWitness(
|
|
960
|
-
|
|
966
|
+
block: BlockParameter,
|
|
961
967
|
l1ToL2Message: Fr,
|
|
962
968
|
): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>] | undefined> {
|
|
963
|
-
const db = await this.#getWorldState(
|
|
969
|
+
const db = await this.#getWorldState(block);
|
|
964
970
|
const [witness] = await db.findSiblingPaths(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, [l1ToL2Message]);
|
|
965
971
|
if (!witness) {
|
|
966
972
|
return undefined;
|
|
@@ -993,12 +999,13 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
993
999
|
* @returns The L2 to L1 messages (empty array if the epoch is not found).
|
|
994
1000
|
*/
|
|
995
1001
|
public async getL2ToL1Messages(epoch: EpochNumber): Promise<Fr[][][][]> {
|
|
996
|
-
// Assumes `
|
|
997
|
-
const
|
|
1002
|
+
// Assumes `getCheckpointedBlocksForEpoch` returns blocks in ascending order of block number.
|
|
1003
|
+
const checkpointedBlocks = await this.blockSource.getCheckpointedBlocksForEpoch(epoch);
|
|
998
1004
|
const blocksInCheckpoints: L2Block[][] = [];
|
|
999
1005
|
let previousSlotNumber = SlotNumber.ZERO;
|
|
1000
1006
|
let checkpointIndex = -1;
|
|
1001
|
-
for (const
|
|
1007
|
+
for (const checkpointedBlock of checkpointedBlocks) {
|
|
1008
|
+
const block = checkpointedBlock.block;
|
|
1002
1009
|
const slotNumber = block.header.globalVariables.slotNumber;
|
|
1003
1010
|
if (slotNumber !== previousSlotNumber) {
|
|
1004
1011
|
checkpointIndex++;
|
|
@@ -1012,45 +1019,27 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1012
1019
|
);
|
|
1013
1020
|
}
|
|
1014
1021
|
|
|
1015
|
-
/**
|
|
1016
|
-
* Returns a sibling path for a leaf in the committed blocks tree.
|
|
1017
|
-
* @param blockNumber - The block number at which to get the data.
|
|
1018
|
-
* @param leafIndex - Index of the leaf in the tree.
|
|
1019
|
-
* @returns The sibling path.
|
|
1020
|
-
*/
|
|
1021
1022
|
public async getArchiveSiblingPath(
|
|
1022
|
-
|
|
1023
|
+
block: BlockParameter,
|
|
1023
1024
|
leafIndex: bigint,
|
|
1024
1025
|
): Promise<SiblingPath<typeof ARCHIVE_HEIGHT>> {
|
|
1025
|
-
const committedDb = await this.#getWorldState(
|
|
1026
|
+
const committedDb = await this.#getWorldState(block);
|
|
1026
1027
|
return committedDb.getSiblingPath(MerkleTreeId.ARCHIVE, leafIndex);
|
|
1027
1028
|
}
|
|
1028
1029
|
|
|
1029
|
-
/**
|
|
1030
|
-
* Returns a sibling path for a leaf in the committed public data tree.
|
|
1031
|
-
* @param blockNumber - The block number at which to get the data.
|
|
1032
|
-
* @param leafIndex - Index of the leaf in the tree.
|
|
1033
|
-
* @returns The sibling path.
|
|
1034
|
-
*/
|
|
1035
1030
|
public async getPublicDataSiblingPath(
|
|
1036
|
-
|
|
1031
|
+
block: BlockParameter,
|
|
1037
1032
|
leafIndex: bigint,
|
|
1038
1033
|
): Promise<SiblingPath<typeof PUBLIC_DATA_TREE_HEIGHT>> {
|
|
1039
|
-
const committedDb = await this.#getWorldState(
|
|
1034
|
+
const committedDb = await this.#getWorldState(block);
|
|
1040
1035
|
return committedDb.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, leafIndex);
|
|
1041
1036
|
}
|
|
1042
1037
|
|
|
1043
|
-
/**
|
|
1044
|
-
* Returns a nullifier membership witness for a given nullifier at a given block.
|
|
1045
|
-
* @param blockNumber - The block number at which to get the index.
|
|
1046
|
-
* @param nullifier - Nullifier we try to find witness for.
|
|
1047
|
-
* @returns The nullifier membership witness (if found).
|
|
1048
|
-
*/
|
|
1049
1038
|
public async getNullifierMembershipWitness(
|
|
1050
|
-
|
|
1039
|
+
block: BlockParameter,
|
|
1051
1040
|
nullifier: Fr,
|
|
1052
1041
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
1053
|
-
const db = await this.#getWorldState(
|
|
1042
|
+
const db = await this.#getWorldState(block);
|
|
1054
1043
|
const [witness] = await db.findSiblingPaths(MerkleTreeId.NULLIFIER_TREE, [nullifier.toBuffer()]);
|
|
1055
1044
|
if (!witness) {
|
|
1056
1045
|
return undefined;
|
|
@@ -1067,7 +1056,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1067
1056
|
|
|
1068
1057
|
/**
|
|
1069
1058
|
* Returns a low nullifier membership witness for a given nullifier at a given block.
|
|
1070
|
-
* @param
|
|
1059
|
+
* @param block - The block parameter (block number, block hash, or 'latest') at which to get the data.
|
|
1071
1060
|
* @param nullifier - Nullifier we try to find the low nullifier witness for.
|
|
1072
1061
|
* @returns The low nullifier membership witness (if found).
|
|
1073
1062
|
* @remarks Low nullifier witness can be used to perform a nullifier non-inclusion proof by leveraging the "linked
|
|
@@ -1080,10 +1069,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1080
1069
|
* TODO: This is a confusing behavior and we should eventually address that.
|
|
1081
1070
|
*/
|
|
1082
1071
|
public async getLowNullifierMembershipWitness(
|
|
1083
|
-
|
|
1072
|
+
block: BlockParameter,
|
|
1084
1073
|
nullifier: Fr,
|
|
1085
1074
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
1086
|
-
const committedDb = await this.#getWorldState(
|
|
1075
|
+
const committedDb = await this.#getWorldState(block);
|
|
1087
1076
|
const findResult = await committedDb.getPreviousValueIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBigInt());
|
|
1088
1077
|
if (!findResult) {
|
|
1089
1078
|
return undefined;
|
|
@@ -1098,8 +1087,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1098
1087
|
return new NullifierMembershipWitness(BigInt(index), preimageData as NullifierLeafPreimage, siblingPath);
|
|
1099
1088
|
}
|
|
1100
1089
|
|
|
1101
|
-
async getPublicDataWitness(
|
|
1102
|
-
const committedDb = await this.#getWorldState(
|
|
1090
|
+
async getPublicDataWitness(block: BlockParameter, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
|
|
1091
|
+
const committedDb = await this.#getWorldState(block);
|
|
1103
1092
|
const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
1104
1093
|
if (!lowLeafResult) {
|
|
1105
1094
|
return undefined;
|
|
@@ -1113,19 +1102,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1113
1102
|
}
|
|
1114
1103
|
}
|
|
1115
1104
|
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
*
|
|
1119
|
-
* @remarks The storage slot here refers to the slot as it is defined in Noir not the index in the merkle tree.
|
|
1120
|
-
* Aztec's version of `eth_getStorageAt`.
|
|
1121
|
-
*
|
|
1122
|
-
* @param contract - Address of the contract to query.
|
|
1123
|
-
* @param slot - Slot to query.
|
|
1124
|
-
* @param blockNumber - The block number at which to get the data or 'latest'.
|
|
1125
|
-
* @returns Storage value at the given contract slot.
|
|
1126
|
-
*/
|
|
1127
|
-
public async getPublicStorageAt(blockNumber: BlockParameter, contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
1128
|
-
const committedDb = await this.#getWorldState(blockNumber);
|
|
1105
|
+
public async getPublicStorageAt(block: BlockParameter, contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
1106
|
+
const committedDb = await this.#getWorldState(block);
|
|
1129
1107
|
const leafSlot = await computePublicDataTreeLeafSlot(contract, slot);
|
|
1130
1108
|
|
|
1131
1109
|
const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
@@ -1139,24 +1117,23 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1139
1117
|
return preimage.leaf.value;
|
|
1140
1118
|
}
|
|
1141
1119
|
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
return await this.blockSource.getBlockHeaderByHash(blockHash);
|
|
1120
|
+
public async getBlockHeader(block: BlockParameter = 'latest'): Promise<BlockHeader | undefined> {
|
|
1121
|
+
if (BlockHash.isL2BlockHash(block)) {
|
|
1122
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
1123
|
+
if (block.equals(initialBlockHash)) {
|
|
1124
|
+
// Block source doesn't handle initial header so we need to handle the case separately.
|
|
1125
|
+
return this.worldStateSynchronizer.getCommitted().getInitialHeader();
|
|
1126
|
+
}
|
|
1127
|
+
const blockHashFr = Fr.fromBuffer(block.toBuffer());
|
|
1128
|
+
return this.blockSource.getBlockHeaderByHash(blockHashFr);
|
|
1129
|
+
} else {
|
|
1130
|
+
// Block source doesn't handle initial header so we need to handle the case separately.
|
|
1131
|
+
const blockNumber = block === 'latest' ? await this.getBlockNumber() : (block as BlockNumber);
|
|
1132
|
+
if (blockNumber === BlockNumber.ZERO) {
|
|
1133
|
+
return this.worldStateSynchronizer.getCommitted().getInitialHeader();
|
|
1134
|
+
}
|
|
1135
|
+
return this.blockSource.getBlockHeader(block);
|
|
1136
|
+
}
|
|
1160
1137
|
}
|
|
1161
1138
|
|
|
1162
1139
|
/**
|
|
@@ -1206,6 +1183,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1206
1183
|
this.contractDataSource,
|
|
1207
1184
|
new DateProvider(),
|
|
1208
1185
|
this.telemetry,
|
|
1186
|
+
this.log.getBindings(),
|
|
1209
1187
|
);
|
|
1210
1188
|
|
|
1211
1189
|
this.log.verbose(`Simulating public calls for tx ${txHash}`, {
|
|
@@ -1259,16 +1237,22 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1259
1237
|
// We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
|
|
1260
1238
|
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
1261
1239
|
const blockNumber = BlockNumber((await this.blockSource.getBlockNumber()) + 1);
|
|
1262
|
-
const validator = createValidatorForAcceptingTxs(
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1240
|
+
const validator = createValidatorForAcceptingTxs(
|
|
1241
|
+
db,
|
|
1242
|
+
this.contractDataSource,
|
|
1243
|
+
verifier,
|
|
1244
|
+
{
|
|
1245
|
+
timestamp: nextSlotTimestamp,
|
|
1246
|
+
blockNumber,
|
|
1247
|
+
l1ChainId: this.l1ChainId,
|
|
1248
|
+
rollupVersion: this.version,
|
|
1249
|
+
setupAllowList: this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions()),
|
|
1250
|
+
gasFees: await this.getCurrentMinFees(),
|
|
1251
|
+
skipFeeEnforcement,
|
|
1252
|
+
txsPermitted: !this.config.disableTransactions,
|
|
1253
|
+
},
|
|
1254
|
+
this.log.getBindings(),
|
|
1255
|
+
);
|
|
1272
1256
|
|
|
1273
1257
|
return await validator.validateTx(tx);
|
|
1274
1258
|
}
|
|
@@ -1432,16 +1416,19 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1432
1416
|
}
|
|
1433
1417
|
}
|
|
1434
1418
|
|
|
1419
|
+
#getInitialHeaderHash(): Promise<BlockHash> {
|
|
1420
|
+
if (!this.initialHeaderHashPromise) {
|
|
1421
|
+
this.initialHeaderHashPromise = this.worldStateSynchronizer.getCommitted().getInitialHeader().hash();
|
|
1422
|
+
}
|
|
1423
|
+
return this.initialHeaderHashPromise;
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1435
1426
|
/**
|
|
1436
1427
|
* Returns an instance of MerkleTreeOperations having first ensured the world state is fully synched
|
|
1437
|
-
* @param
|
|
1428
|
+
* @param block - The block parameter (block number, block hash, or 'latest') at which to get the data.
|
|
1438
1429
|
* @returns An instance of a committed MerkleTreeOperations
|
|
1439
1430
|
*/
|
|
1440
|
-
async #getWorldState(
|
|
1441
|
-
if (typeof blockNumber === 'number' && blockNumber < INITIAL_L2_BLOCK_NUM - 1) {
|
|
1442
|
-
throw new Error('Invalid block number to get world state for: ' + blockNumber);
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1431
|
+
async #getWorldState(block: BlockParameter) {
|
|
1445
1432
|
let blockSyncedTo: BlockNumber = BlockNumber.ZERO;
|
|
1446
1433
|
try {
|
|
1447
1434
|
// Attempt to sync the world state if necessary
|
|
@@ -1450,15 +1437,40 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1450
1437
|
this.log.error(`Error getting world state: ${err}`);
|
|
1451
1438
|
}
|
|
1452
1439
|
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
this.log.debug(`Using committed db for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
|
|
1440
|
+
if (block === 'latest') {
|
|
1441
|
+
this.log.debug(`Using committed db for block 'latest', world state synced upto ${blockSyncedTo}`);
|
|
1456
1442
|
return this.worldStateSynchronizer.getCommitted();
|
|
1457
|
-
}
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
if (BlockHash.isL2BlockHash(block)) {
|
|
1446
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
1447
|
+
if (block.equals(initialBlockHash)) {
|
|
1448
|
+
// Block source doesn't handle initial header so we need to handle the case separately.
|
|
1449
|
+
return this.worldStateSynchronizer.getSnapshot(BlockNumber.ZERO);
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
const blockHashFr = Fr.fromBuffer(block.toBuffer());
|
|
1453
|
+
const header = await this.blockSource.getBlockHeaderByHash(blockHashFr);
|
|
1454
|
+
if (!header) {
|
|
1455
|
+
throw new Error(
|
|
1456
|
+
`Block hash ${block.toString()} not found when querying world state. If the node API has been queried with anchor block hash possibly a reorg has occurred.`,
|
|
1457
|
+
);
|
|
1458
|
+
}
|
|
1459
|
+
const blockNumber = header.getBlockNumber();
|
|
1458
1460
|
this.log.debug(`Using snapshot for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
|
|
1459
|
-
return this.worldStateSynchronizer.getSnapshot(blockNumber
|
|
1460
|
-
}
|
|
1461
|
-
|
|
1461
|
+
return this.worldStateSynchronizer.getSnapshot(blockNumber);
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
// Block number provided
|
|
1465
|
+
{
|
|
1466
|
+
const blockNumber = block as BlockNumber;
|
|
1467
|
+
|
|
1468
|
+
if (blockNumber > blockSyncedTo) {
|
|
1469
|
+
throw new Error(`Queried block ${block} not yet synced by the node (node is synced upto ${blockSyncedTo}).`);
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
this.log.debug(`Using snapshot for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
|
|
1473
|
+
return this.worldStateSynchronizer.getSnapshot(blockNumber);
|
|
1462
1474
|
}
|
|
1463
1475
|
}
|
|
1464
1476
|
|
package/src/sentinel/factory.ts
CHANGED
|
@@ -20,12 +20,7 @@ export async function createSentinel(
|
|
|
20
20
|
if (!config.sentinelEnabled) {
|
|
21
21
|
return undefined;
|
|
22
22
|
}
|
|
23
|
-
const kvStore = await createStore(
|
|
24
|
-
'sentinel',
|
|
25
|
-
SentinelStore.SCHEMA_VERSION,
|
|
26
|
-
config,
|
|
27
|
-
createLogger('node:sentinel:lmdb'),
|
|
28
|
-
);
|
|
23
|
+
const kvStore = await createStore('sentinel', SentinelStore.SCHEMA_VERSION, config, logger.getBindings());
|
|
29
24
|
const storeHistoryLength = config.sentinelHistoryLengthInEpochs * epochCache.getL1Constants().epochDuration;
|
|
30
25
|
const storeHistoricProvenPerformanceLength = config.sentinelHistoricProvenPerformanceLengthInEpochs;
|
|
31
26
|
const sentinelStore = new SentinelStore(kvStore, {
|