@aztec/aztec-node 0.0.1-commit.6230efd → 0.0.1-commit.64b6bbb
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 +9 -16
- package/dest/aztec-node/server.d.ts +39 -98
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +572 -185
- 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.d.ts +5 -4
- package/dest/sentinel/sentinel.d.ts.map +1 -1
- package/dest/sentinel/sentinel.js +31 -26
- package/dest/sentinel/store.d.ts +2 -2
- package/dest/sentinel/store.d.ts.map +1 -1
- package/package.json +26 -26
- package/src/aztec-node/node_metrics.ts +6 -17
- package/src/aztec-node/server.ts +238 -248
- package/src/sentinel/factory.ts +1 -6
- package/src/sentinel/sentinel.ts +41 -32
package/src/aztec-node/server.ts
CHANGED
|
@@ -1,25 +1,13 @@
|
|
|
1
1
|
import { Archiver, createArchiver } from '@aztec/archiver';
|
|
2
2
|
import { BBCircuitVerifier, QueuedIVCVerifier, TestCircuitVerifier } from '@aztec/bb-prover';
|
|
3
|
-
import { type BlobClientInterface,
|
|
4
|
-
import {
|
|
5
|
-
type BlobFileStoreMetadata,
|
|
6
|
-
createReadOnlyFileStoreBlobClients,
|
|
7
|
-
createWritableFileStoreBlobClient,
|
|
8
|
-
} from '@aztec/blob-client/filestore';
|
|
9
|
-
import {
|
|
10
|
-
ARCHIVE_HEIGHT,
|
|
11
|
-
INITIAL_L2_BLOCK_NUM,
|
|
12
|
-
type L1_TO_L2_MSG_TREE_HEIGHT,
|
|
13
|
-
type NOTE_HASH_TREE_HEIGHT,
|
|
14
|
-
type NULLIFIER_TREE_HEIGHT,
|
|
15
|
-
type PUBLIC_DATA_TREE_HEIGHT,
|
|
16
|
-
} from '@aztec/constants';
|
|
3
|
+
import { type BlobClientInterface, createBlobClientWithFileStores } from '@aztec/blob-client/client';
|
|
4
|
+
import { ARCHIVE_HEIGHT, type L1_TO_L2_MSG_TREE_HEIGHT, type NOTE_HASH_TREE_HEIGHT } from '@aztec/constants';
|
|
17
5
|
import { EpochCache, type EpochCacheInterface } from '@aztec/epoch-cache';
|
|
18
6
|
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
19
7
|
import { getPublicClient } from '@aztec/ethereum/client';
|
|
20
8
|
import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
21
9
|
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
22
|
-
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
10
|
+
import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
23
11
|
import { compactArray, pick } from '@aztec/foundation/collection';
|
|
24
12
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
25
13
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
@@ -36,14 +24,7 @@ import {
|
|
|
36
24
|
} from '@aztec/node-lib/factories';
|
|
37
25
|
import { type P2P, type P2PClientDeps, createP2PClient, getDefaultAllowedSetupFunctions } from '@aztec/p2p';
|
|
38
26
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
39
|
-
import {
|
|
40
|
-
BlockBuilder,
|
|
41
|
-
GlobalVariableBuilder,
|
|
42
|
-
SequencerClient,
|
|
43
|
-
type SequencerPublisher,
|
|
44
|
-
createValidatorForAcceptingTxs,
|
|
45
|
-
} from '@aztec/sequencer-client';
|
|
46
|
-
import { CheckpointsBuilder } from '@aztec/sequencer-client';
|
|
27
|
+
import { GlobalVariableBuilder, SequencerClient, type SequencerPublisher } from '@aztec/sequencer-client';
|
|
47
28
|
import { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
48
29
|
import {
|
|
49
30
|
AttestationsBlockWatcher,
|
|
@@ -54,14 +35,8 @@ import {
|
|
|
54
35
|
} from '@aztec/slasher';
|
|
55
36
|
import { CollectionLimitsConfig, PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
56
37
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
57
|
-
import {
|
|
58
|
-
|
|
59
|
-
type DataInBlock,
|
|
60
|
-
type L2Block,
|
|
61
|
-
L2BlockHash,
|
|
62
|
-
type L2BlockSource,
|
|
63
|
-
type PublishedL2Block,
|
|
64
|
-
} from '@aztec/stdlib/block';
|
|
38
|
+
import { BlockHash, type BlockParameter, type DataInBlock, L2Block, type L2BlockSource } from '@aztec/stdlib/block';
|
|
39
|
+
import type { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
65
40
|
import type {
|
|
66
41
|
ContractClassPublic,
|
|
67
42
|
ContractDataSource,
|
|
@@ -116,10 +91,13 @@ import {
|
|
|
116
91
|
trackSpan,
|
|
117
92
|
} from '@aztec/telemetry-client';
|
|
118
93
|
import {
|
|
94
|
+
FullNodeCheckpointsBuilder as CheckpointsBuilder,
|
|
95
|
+
FullNodeCheckpointsBuilder,
|
|
119
96
|
NodeKeystoreAdapter,
|
|
120
97
|
ValidatorClient,
|
|
121
98
|
createBlockProposalHandler,
|
|
122
99
|
createValidatorClient,
|
|
100
|
+
createValidatorForAcceptingTxs,
|
|
123
101
|
} from '@aztec/validator-client';
|
|
124
102
|
import { createWorldStateSynchronizer } from '@aztec/world-state';
|
|
125
103
|
|
|
@@ -135,6 +113,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
135
113
|
*/
|
|
136
114
|
export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
137
115
|
private metrics: NodeMetrics;
|
|
116
|
+
private initialHeaderHashPromise: Promise<BlockHash> | undefined = undefined;
|
|
138
117
|
|
|
139
118
|
// Prevent two snapshot operations to happen simultaneously
|
|
140
119
|
private isUploadingSnapshot = false;
|
|
@@ -191,7 +170,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
191
170
|
logger?: Logger;
|
|
192
171
|
publisher?: SequencerPublisher;
|
|
193
172
|
dateProvider?: DateProvider;
|
|
194
|
-
blobClient?: BlobClientInterface;
|
|
195
173
|
p2pClientDeps?: P2PClientDeps<P2PClientType.Full>;
|
|
196
174
|
} = {},
|
|
197
175
|
options: {
|
|
@@ -271,24 +249,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
271
249
|
);
|
|
272
250
|
}
|
|
273
251
|
|
|
274
|
-
const
|
|
275
|
-
l1ChainId: config.l1ChainId,
|
|
276
|
-
rollupVersion: config.rollupVersion,
|
|
277
|
-
rollupAddress: config.l1Contracts.rollupAddress.toString(),
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
const [fileStoreClients, fileStoreUploadClient] = await Promise.all([
|
|
281
|
-
createReadOnlyFileStoreBlobClients(config.blobFileStoreUrls, blobFileStoreMetadata, log),
|
|
282
|
-
createWritableFileStoreBlobClient(config.blobFileStoreUploadUrl, blobFileStoreMetadata, log),
|
|
283
|
-
]);
|
|
284
|
-
|
|
285
|
-
const blobClient =
|
|
286
|
-
deps.blobClient ??
|
|
287
|
-
createBlobClient(config, {
|
|
288
|
-
logger: createLogger('node:blob-client:client'),
|
|
289
|
-
fileStoreClients,
|
|
290
|
-
fileStoreUploadClient,
|
|
291
|
-
});
|
|
252
|
+
const blobClient = await createBlobClientWithFileStores(config, createLogger('node:blob-client:client'));
|
|
292
253
|
|
|
293
254
|
// attempt snapshot sync if possible
|
|
294
255
|
await trySnapshotSync(config, log);
|
|
@@ -334,7 +295,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
334
295
|
// We should really not be modifying the config object
|
|
335
296
|
config.txPublicSetupAllowList = config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
|
|
336
297
|
|
|
337
|
-
|
|
298
|
+
// Create FullNodeCheckpointsBuilder for validator and non-validator block proposal handling
|
|
299
|
+
const validatorCheckpointsBuilder = new FullNodeCheckpointsBuilder(
|
|
338
300
|
{ ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
|
|
339
301
|
worldStateSynchronizer,
|
|
340
302
|
archiver,
|
|
@@ -346,16 +308,17 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
346
308
|
const watchers: Watcher[] = [];
|
|
347
309
|
|
|
348
310
|
// Create validator client if required
|
|
349
|
-
const validatorClient = createValidatorClient(config, {
|
|
311
|
+
const validatorClient = await createValidatorClient(config, {
|
|
312
|
+
checkpointsBuilder: validatorCheckpointsBuilder,
|
|
313
|
+
worldState: worldStateSynchronizer,
|
|
350
314
|
p2pClient,
|
|
351
315
|
telemetry,
|
|
352
316
|
dateProvider,
|
|
353
317
|
epochCache,
|
|
354
|
-
blockBuilder,
|
|
355
318
|
blockSource: archiver,
|
|
356
319
|
l1ToL2MessageSource: archiver,
|
|
357
320
|
keyStoreManager,
|
|
358
|
-
|
|
321
|
+
blobClient,
|
|
359
322
|
});
|
|
360
323
|
|
|
361
324
|
// If we have a validator client, register it as a source of offenses for the slasher,
|
|
@@ -373,7 +336,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
373
336
|
if (!validatorClient && config.alwaysReexecuteBlockProposals) {
|
|
374
337
|
log.info('Setting up block proposal reexecution for monitoring');
|
|
375
338
|
createBlockProposalHandler(config, {
|
|
376
|
-
|
|
339
|
+
checkpointsBuilder: validatorCheckpointsBuilder,
|
|
340
|
+
worldState: worldStateSynchronizer,
|
|
377
341
|
epochCache,
|
|
378
342
|
blockSource: archiver,
|
|
379
343
|
l1ToL2MessageSource: archiver,
|
|
@@ -401,7 +365,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
401
365
|
archiver,
|
|
402
366
|
epochCache,
|
|
403
367
|
p2pClient.getTxProvider(),
|
|
404
|
-
|
|
368
|
+
validatorCheckpointsBuilder,
|
|
405
369
|
config,
|
|
406
370
|
);
|
|
407
371
|
watchers.push(epochPruneWatcher);
|
|
@@ -466,6 +430,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
466
430
|
// Create and start the sequencer client
|
|
467
431
|
const checkpointsBuilder = new CheckpointsBuilder(
|
|
468
432
|
{ ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
|
|
433
|
+
worldStateSynchronizer,
|
|
469
434
|
archiver,
|
|
470
435
|
dateProvider,
|
|
471
436
|
telemetry,
|
|
@@ -594,13 +559,19 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
594
559
|
}
|
|
595
560
|
|
|
596
561
|
/**
|
|
597
|
-
* Get a block specified by its number.
|
|
598
|
-
* @param
|
|
562
|
+
* Get a block specified by its block number, block hash, or 'latest'.
|
|
563
|
+
* @param block - The block parameter (block number, block hash, or 'latest').
|
|
599
564
|
* @returns The requested block.
|
|
600
565
|
*/
|
|
601
|
-
public async getBlock(
|
|
602
|
-
|
|
603
|
-
|
|
566
|
+
public async getBlock(block: BlockParameter): Promise<L2Block | undefined> {
|
|
567
|
+
if (BlockHash.isBlockHash(block)) {
|
|
568
|
+
return this.getBlockByHash(block);
|
|
569
|
+
}
|
|
570
|
+
const blockNumber = block === 'latest' ? await this.getBlockNumber() : (block as BlockNumber);
|
|
571
|
+
if (blockNumber === BlockNumber.ZERO) {
|
|
572
|
+
return this.buildInitialBlock();
|
|
573
|
+
}
|
|
574
|
+
return await this.blockSource.getL2Block(blockNumber);
|
|
604
575
|
}
|
|
605
576
|
|
|
606
577
|
/**
|
|
@@ -608,9 +579,17 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
608
579
|
* @param blockHash - The block hash being requested.
|
|
609
580
|
* @returns The requested block.
|
|
610
581
|
*/
|
|
611
|
-
public async getBlockByHash(blockHash:
|
|
612
|
-
const
|
|
613
|
-
|
|
582
|
+
public async getBlockByHash(blockHash: BlockHash): Promise<L2Block | undefined> {
|
|
583
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
584
|
+
if (blockHash.equals(initialBlockHash)) {
|
|
585
|
+
return this.buildInitialBlock();
|
|
586
|
+
}
|
|
587
|
+
return await this.blockSource.getL2BlockByHash(blockHash);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
private buildInitialBlock(): L2Block {
|
|
591
|
+
const initialHeader = this.worldStateSynchronizer.getCommitted().getInitialHeader();
|
|
592
|
+
return L2Block.empty(initialHeader);
|
|
614
593
|
}
|
|
615
594
|
|
|
616
595
|
/**
|
|
@@ -619,8 +598,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
619
598
|
* @returns The requested block.
|
|
620
599
|
*/
|
|
621
600
|
public async getBlockByArchive(archive: Fr): Promise<L2Block | undefined> {
|
|
622
|
-
|
|
623
|
-
return publishedBlock?.block;
|
|
601
|
+
return await this.blockSource.getL2BlockByArchive(archive);
|
|
624
602
|
}
|
|
625
603
|
|
|
626
604
|
/**
|
|
@@ -630,19 +608,23 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
630
608
|
* @returns The blocks requested.
|
|
631
609
|
*/
|
|
632
610
|
public async getBlocks(from: BlockNumber, limit: number): Promise<L2Block[]> {
|
|
633
|
-
return (await this.blockSource.getBlocks(from, limit)) ?? [];
|
|
611
|
+
return (await this.blockSource.getBlocks(from, BlockNumber(limit))) ?? [];
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
public async getCheckpoints(from: CheckpointNumber, limit: number): Promise<PublishedCheckpoint[]> {
|
|
615
|
+
return (await this.blockSource.getCheckpoints(from, limit)) ?? [];
|
|
634
616
|
}
|
|
635
617
|
|
|
636
|
-
public async
|
|
637
|
-
return (await this.blockSource.
|
|
618
|
+
public async getCheckpointedBlocks(from: BlockNumber, limit: number) {
|
|
619
|
+
return (await this.blockSource.getCheckpointedBlocks(from, limit)) ?? [];
|
|
638
620
|
}
|
|
639
621
|
|
|
640
622
|
/**
|
|
641
|
-
* Method to fetch the current
|
|
642
|
-
* @returns The current
|
|
623
|
+
* Method to fetch the current min L2 fees.
|
|
624
|
+
* @returns The current min L2 fees.
|
|
643
625
|
*/
|
|
644
|
-
public async
|
|
645
|
-
return await this.globalVariableBuilder.
|
|
626
|
+
public async getCurrentMinFees(): Promise<GasFees> {
|
|
627
|
+
return await this.globalVariableBuilder.getCurrentMinFees();
|
|
646
628
|
}
|
|
647
629
|
|
|
648
630
|
public async getMaxPriorityFees(): Promise<GasFees> {
|
|
@@ -665,6 +647,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
665
647
|
return await this.blockSource.getProvenBlockNumber();
|
|
666
648
|
}
|
|
667
649
|
|
|
650
|
+
public async getCheckpointedBlockNumber(): Promise<BlockNumber> {
|
|
651
|
+
return await this.blockSource.getCheckpointedL2BlockNumber();
|
|
652
|
+
}
|
|
653
|
+
|
|
668
654
|
/**
|
|
669
655
|
* Method to fetch the version of the package.
|
|
670
656
|
* @returns The node package version
|
|
@@ -697,12 +683,43 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
697
683
|
return this.contractDataSource.getContract(address);
|
|
698
684
|
}
|
|
699
685
|
|
|
700
|
-
public getPrivateLogsByTags(
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
686
|
+
public async getPrivateLogsByTags(
|
|
687
|
+
tags: SiloedTag[],
|
|
688
|
+
page?: number,
|
|
689
|
+
referenceBlock?: BlockHash,
|
|
690
|
+
): Promise<TxScopedL2Log[][]> {
|
|
691
|
+
if (referenceBlock) {
|
|
692
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
693
|
+
if (!referenceBlock.equals(initialBlockHash)) {
|
|
694
|
+
const header = await this.blockSource.getBlockHeaderByHash(referenceBlock);
|
|
695
|
+
if (!header) {
|
|
696
|
+
throw new Error(
|
|
697
|
+
`Block ${referenceBlock.toString()} not found in the node. This might indicate a reorg has occurred.`,
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
return this.logsSource.getPrivateLogsByTags(tags, page);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
public async getPublicLogsByTagsFromContract(
|
|
706
|
+
contractAddress: AztecAddress,
|
|
707
|
+
tags: Tag[],
|
|
708
|
+
page?: number,
|
|
709
|
+
referenceBlock?: BlockHash,
|
|
710
|
+
): Promise<TxScopedL2Log[][]> {
|
|
711
|
+
if (referenceBlock) {
|
|
712
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
713
|
+
if (!referenceBlock.equals(initialBlockHash)) {
|
|
714
|
+
const header = await this.blockSource.getBlockHeaderByHash(referenceBlock);
|
|
715
|
+
if (!header) {
|
|
716
|
+
throw new Error(
|
|
717
|
+
`Block ${referenceBlock.toString()} not found in the node. This might indicate a reorg has occurred.`,
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
return this.logsSource.getPublicLogsByTagsFromContract(contractAddress, tags, page);
|
|
706
723
|
}
|
|
707
724
|
|
|
708
725
|
/**
|
|
@@ -749,21 +766,26 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
749
766
|
}
|
|
750
767
|
|
|
751
768
|
public async getTxReceipt(txHash: TxHash): Promise<TxReceipt> {
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
// and we would incorrectly return a TxReceipt with status DROPPED
|
|
757
|
-
if ((await this.p2pClient.getTxStatus(txHash)) === 'pending') {
|
|
758
|
-
txReceipt = new TxReceipt(txHash, TxStatus.PENDING, '');
|
|
759
|
-
}
|
|
769
|
+
// Check the tx pool status first. If the tx is known to the pool (pending or mined), we'll use that
|
|
770
|
+
// as a fallback if we don't find a settled receipt in the archiver.
|
|
771
|
+
const txPoolStatus = await this.p2pClient.getTxStatus(txHash);
|
|
772
|
+
const isKnownToPool = txPoolStatus === 'pending' || txPoolStatus === 'mined';
|
|
760
773
|
|
|
774
|
+
// Then get the actual tx from the archiver, which tracks every tx in a mined block.
|
|
761
775
|
const settledTxReceipt = await this.blockSource.getSettledTxReceipt(txHash);
|
|
776
|
+
|
|
762
777
|
if (settledTxReceipt) {
|
|
763
|
-
|
|
778
|
+
// If the archiver has the receipt then return it.
|
|
779
|
+
return settledTxReceipt;
|
|
780
|
+
} else if (isKnownToPool) {
|
|
781
|
+
// If the tx is in the pool but not in the archiver, it's pending.
|
|
782
|
+
// This handles race conditions between archiver and p2p, where the archiver
|
|
783
|
+
// has pruned the block in which a tx was mined, but p2p has not caught up yet.
|
|
784
|
+
return new TxReceipt(txHash, TxStatus.PENDING, undefined, undefined);
|
|
785
|
+
} else {
|
|
786
|
+
// Otherwise, if we don't know the tx, we consider it dropped.
|
|
787
|
+
return new TxReceipt(txHash, TxStatus.DROPPED, undefined, 'Tx dropped by P2P node');
|
|
764
788
|
}
|
|
765
|
-
|
|
766
|
-
return txReceipt;
|
|
767
789
|
}
|
|
768
790
|
|
|
769
791
|
public getTxEffect(txHash: TxHash): Promise<IndexedTxEffect | undefined> {
|
|
@@ -788,6 +810,14 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
788
810
|
this.log.info(`Stopped Aztec Node`);
|
|
789
811
|
}
|
|
790
812
|
|
|
813
|
+
/**
|
|
814
|
+
* Returns the blob client used by this node.
|
|
815
|
+
* @internal - Exposed for testing purposes only.
|
|
816
|
+
*/
|
|
817
|
+
public getBlobClient(): BlobClientInterface | undefined {
|
|
818
|
+
return this.blobClient;
|
|
819
|
+
}
|
|
820
|
+
|
|
791
821
|
/**
|
|
792
822
|
* Method to retrieve pending txs.
|
|
793
823
|
* @param limit - The number of items to returns
|
|
@@ -820,20 +850,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
820
850
|
return compactArray(await Promise.all(txHashes.map(txHash => this.getTxByHash(txHash))));
|
|
821
851
|
}
|
|
822
852
|
|
|
823
|
-
/**
|
|
824
|
-
* Find the indexes of the given leaves in the given tree along with a block metadata pointing to the block in which
|
|
825
|
-
* the leaves were inserted.
|
|
826
|
-
* @param blockNumber - The block number at which to get the data or 'latest' for latest data.
|
|
827
|
-
* @param treeId - The tree to search in.
|
|
828
|
-
* @param leafValues - The values to search for.
|
|
829
|
-
* @returns The indices of leaves and the block metadata of a block in which the leaves were inserted.
|
|
830
|
-
*/
|
|
831
853
|
public async findLeavesIndexes(
|
|
832
|
-
|
|
854
|
+
referenceBlock: BlockParameter,
|
|
833
855
|
treeId: MerkleTreeId,
|
|
834
856
|
leafValues: Fr[],
|
|
835
857
|
): Promise<(DataInBlock<bigint> | undefined)[]> {
|
|
836
|
-
const committedDb = await this.#getWorldState(
|
|
858
|
+
const committedDb = await this.#getWorldState(referenceBlock);
|
|
837
859
|
const maybeIndices = await committedDb.findLeafIndices(
|
|
838
860
|
treeId,
|
|
839
861
|
leafValues.map(x => x.toBuffer()),
|
|
@@ -885,56 +907,28 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
885
907
|
}
|
|
886
908
|
return {
|
|
887
909
|
l2BlockNumber: BlockNumber(Number(blockNumber)),
|
|
888
|
-
l2BlockHash:
|
|
910
|
+
l2BlockHash: new BlockHash(blockHash),
|
|
889
911
|
data: index,
|
|
890
912
|
};
|
|
891
913
|
});
|
|
892
914
|
}
|
|
893
915
|
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
* @param leafIndex - The index of the leaf for which the sibling path is required.
|
|
898
|
-
* @returns The sibling path for the leaf index.
|
|
899
|
-
*/
|
|
900
|
-
public async getNullifierSiblingPath(
|
|
901
|
-
blockNumber: BlockParameter,
|
|
902
|
-
leafIndex: bigint,
|
|
903
|
-
): Promise<SiblingPath<typeof NULLIFIER_TREE_HEIGHT>> {
|
|
904
|
-
const committedDb = await this.#getWorldState(blockNumber);
|
|
905
|
-
return committedDb.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, leafIndex);
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
/**
|
|
909
|
-
* Returns a sibling path for the given index in the data tree.
|
|
910
|
-
* @param blockNumber - The block number at which to get the data.
|
|
911
|
-
* @param leafIndex - The index of the leaf for which the sibling path is required.
|
|
912
|
-
* @returns The sibling path for the leaf index.
|
|
913
|
-
*/
|
|
914
|
-
public async getNoteHashSiblingPath(
|
|
915
|
-
blockNumber: BlockParameter,
|
|
916
|
-
leafIndex: bigint,
|
|
917
|
-
): Promise<SiblingPath<typeof NOTE_HASH_TREE_HEIGHT>> {
|
|
918
|
-
const committedDb = await this.#getWorldState(blockNumber);
|
|
919
|
-
return committedDb.getSiblingPath(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
public async getArchiveMembershipWitness(
|
|
923
|
-
blockNumber: BlockParameter,
|
|
924
|
-
archive: Fr,
|
|
916
|
+
public async getBlockHashMembershipWitness(
|
|
917
|
+
referenceBlock: BlockParameter,
|
|
918
|
+
blockHash: BlockHash,
|
|
925
919
|
): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined> {
|
|
926
|
-
const committedDb = await this.#getWorldState(
|
|
927
|
-
const [pathAndIndex] = await committedDb.findSiblingPaths<MerkleTreeId.ARCHIVE>(MerkleTreeId.ARCHIVE, [
|
|
920
|
+
const committedDb = await this.#getWorldState(referenceBlock);
|
|
921
|
+
const [pathAndIndex] = await committedDb.findSiblingPaths<MerkleTreeId.ARCHIVE>(MerkleTreeId.ARCHIVE, [blockHash]);
|
|
928
922
|
return pathAndIndex === undefined
|
|
929
923
|
? undefined
|
|
930
924
|
: MembershipWitness.fromSiblingPath(pathAndIndex.index, pathAndIndex.path);
|
|
931
925
|
}
|
|
932
926
|
|
|
933
927
|
public async getNoteHashMembershipWitness(
|
|
934
|
-
|
|
928
|
+
referenceBlock: BlockParameter,
|
|
935
929
|
noteHash: Fr,
|
|
936
930
|
): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
|
|
937
|
-
const committedDb = await this.#getWorldState(
|
|
931
|
+
const committedDb = await this.#getWorldState(referenceBlock);
|
|
938
932
|
const [pathAndIndex] = await committedDb.findSiblingPaths<MerkleTreeId.NOTE_HASH_TREE>(
|
|
939
933
|
MerkleTreeId.NOTE_HASH_TREE,
|
|
940
934
|
[noteHash],
|
|
@@ -944,17 +938,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
944
938
|
: MembershipWitness.fromSiblingPath(pathAndIndex.index, pathAndIndex.path);
|
|
945
939
|
}
|
|
946
940
|
|
|
947
|
-
/**
|
|
948
|
-
* Returns the index and a sibling path for a leaf in the committed l1 to l2 data tree.
|
|
949
|
-
* @param blockNumber - The block number at which to get the data.
|
|
950
|
-
* @param l1ToL2Message - The l1ToL2Message to get the index / sibling path for.
|
|
951
|
-
* @returns A tuple of the index and the sibling path of the L1ToL2Message (undefined if not found).
|
|
952
|
-
*/
|
|
953
941
|
public async getL1ToL2MessageMembershipWitness(
|
|
954
|
-
|
|
942
|
+
referenceBlock: BlockParameter,
|
|
955
943
|
l1ToL2Message: Fr,
|
|
956
944
|
): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>] | undefined> {
|
|
957
|
-
const db = await this.#getWorldState(
|
|
945
|
+
const db = await this.#getWorldState(referenceBlock);
|
|
958
946
|
const [witness] = await db.findSiblingPaths(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, [l1ToL2Message]);
|
|
959
947
|
if (!witness) {
|
|
960
948
|
return undefined;
|
|
@@ -982,56 +970,36 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
982
970
|
}
|
|
983
971
|
|
|
984
972
|
/**
|
|
985
|
-
* Returns all the L2 to L1 messages in
|
|
986
|
-
* @param
|
|
987
|
-
* @returns The L2 to L1 messages (
|
|
973
|
+
* Returns all the L2 to L1 messages in an epoch.
|
|
974
|
+
* @param epoch - The epoch at which to get the data.
|
|
975
|
+
* @returns The L2 to L1 messages (empty array if the epoch is not found).
|
|
988
976
|
*/
|
|
989
|
-
public async getL2ToL1Messages(
|
|
990
|
-
|
|
991
|
-
|
|
977
|
+
public async getL2ToL1Messages(epoch: EpochNumber): Promise<Fr[][][][]> {
|
|
978
|
+
// Assumes `getCheckpointedBlocksForEpoch` returns blocks in ascending order of block number.
|
|
979
|
+
const checkpointedBlocks = await this.blockSource.getCheckpointedBlocksForEpoch(epoch);
|
|
980
|
+
const blocksInCheckpoints: L2Block[][] = [];
|
|
981
|
+
let previousSlotNumber = SlotNumber.ZERO;
|
|
982
|
+
let checkpointIndex = -1;
|
|
983
|
+
for (const checkpointedBlock of checkpointedBlocks) {
|
|
984
|
+
const block = checkpointedBlock.block;
|
|
985
|
+
const slotNumber = block.header.globalVariables.slotNumber;
|
|
986
|
+
if (slotNumber !== previousSlotNumber) {
|
|
987
|
+
checkpointIndex++;
|
|
988
|
+
blocksInCheckpoints.push([]);
|
|
989
|
+
previousSlotNumber = slotNumber;
|
|
990
|
+
}
|
|
991
|
+
blocksInCheckpoints[checkpointIndex].push(block);
|
|
992
|
+
}
|
|
993
|
+
return blocksInCheckpoints.map(blocks =>
|
|
994
|
+
blocks.map(block => block.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs)),
|
|
992
995
|
);
|
|
993
|
-
return block?.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs);
|
|
994
996
|
}
|
|
995
997
|
|
|
996
|
-
/**
|
|
997
|
-
* Returns a sibling path for a leaf in the committed blocks tree.
|
|
998
|
-
* @param blockNumber - The block number at which to get the data.
|
|
999
|
-
* @param leafIndex - Index of the leaf in the tree.
|
|
1000
|
-
* @returns The sibling path.
|
|
1001
|
-
*/
|
|
1002
|
-
public async getArchiveSiblingPath(
|
|
1003
|
-
blockNumber: BlockParameter,
|
|
1004
|
-
leafIndex: bigint,
|
|
1005
|
-
): Promise<SiblingPath<typeof ARCHIVE_HEIGHT>> {
|
|
1006
|
-
const committedDb = await this.#getWorldState(blockNumber);
|
|
1007
|
-
return committedDb.getSiblingPath(MerkleTreeId.ARCHIVE, leafIndex);
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
/**
|
|
1011
|
-
* Returns a sibling path for a leaf in the committed public data tree.
|
|
1012
|
-
* @param blockNumber - The block number at which to get the data.
|
|
1013
|
-
* @param leafIndex - Index of the leaf in the tree.
|
|
1014
|
-
* @returns The sibling path.
|
|
1015
|
-
*/
|
|
1016
|
-
public async getPublicDataSiblingPath(
|
|
1017
|
-
blockNumber: BlockParameter,
|
|
1018
|
-
leafIndex: bigint,
|
|
1019
|
-
): Promise<SiblingPath<typeof PUBLIC_DATA_TREE_HEIGHT>> {
|
|
1020
|
-
const committedDb = await this.#getWorldState(blockNumber);
|
|
1021
|
-
return committedDb.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, leafIndex);
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
/**
|
|
1025
|
-
* Returns a nullifier membership witness for a given nullifier at a given block.
|
|
1026
|
-
* @param blockNumber - The block number at which to get the index.
|
|
1027
|
-
* @param nullifier - Nullifier we try to find witness for.
|
|
1028
|
-
* @returns The nullifier membership witness (if found).
|
|
1029
|
-
*/
|
|
1030
998
|
public async getNullifierMembershipWitness(
|
|
1031
|
-
|
|
999
|
+
referenceBlock: BlockParameter,
|
|
1032
1000
|
nullifier: Fr,
|
|
1033
1001
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
1034
|
-
const db = await this.#getWorldState(
|
|
1002
|
+
const db = await this.#getWorldState(referenceBlock);
|
|
1035
1003
|
const [witness] = await db.findSiblingPaths(MerkleTreeId.NULLIFIER_TREE, [nullifier.toBuffer()]);
|
|
1036
1004
|
if (!witness) {
|
|
1037
1005
|
return undefined;
|
|
@@ -1048,7 +1016,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1048
1016
|
|
|
1049
1017
|
/**
|
|
1050
1018
|
* Returns a low nullifier membership witness for a given nullifier at a given block.
|
|
1051
|
-
* @param
|
|
1019
|
+
* @param referenceBlock - The block parameter (block number, block hash, or 'latest') at which to get the data
|
|
1020
|
+
* (which contains the root of the nullifier tree in which we are searching for the nullifier).
|
|
1052
1021
|
* @param nullifier - Nullifier we try to find the low nullifier witness for.
|
|
1053
1022
|
* @returns The low nullifier membership witness (if found).
|
|
1054
1023
|
* @remarks Low nullifier witness can be used to perform a nullifier non-inclusion proof by leveraging the "linked
|
|
@@ -1061,10 +1030,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1061
1030
|
* TODO: This is a confusing behavior and we should eventually address that.
|
|
1062
1031
|
*/
|
|
1063
1032
|
public async getLowNullifierMembershipWitness(
|
|
1064
|
-
|
|
1033
|
+
referenceBlock: BlockParameter,
|
|
1065
1034
|
nullifier: Fr,
|
|
1066
1035
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
1067
|
-
const committedDb = await this.#getWorldState(
|
|
1036
|
+
const committedDb = await this.#getWorldState(referenceBlock);
|
|
1068
1037
|
const findResult = await committedDb.getPreviousValueIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBigInt());
|
|
1069
1038
|
if (!findResult) {
|
|
1070
1039
|
return undefined;
|
|
@@ -1079,8 +1048,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1079
1048
|
return new NullifierMembershipWitness(BigInt(index), preimageData as NullifierLeafPreimage, siblingPath);
|
|
1080
1049
|
}
|
|
1081
1050
|
|
|
1082
|
-
async getPublicDataWitness(
|
|
1083
|
-
const committedDb = await this.#getWorldState(
|
|
1051
|
+
async getPublicDataWitness(referenceBlock: BlockParameter, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
|
|
1052
|
+
const committedDb = await this.#getWorldState(referenceBlock);
|
|
1084
1053
|
const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
1085
1054
|
if (!lowLeafResult) {
|
|
1086
1055
|
return undefined;
|
|
@@ -1094,19 +1063,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1094
1063
|
}
|
|
1095
1064
|
}
|
|
1096
1065
|
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
*
|
|
1100
|
-
* @remarks The storage slot here refers to the slot as it is defined in Noir not the index in the merkle tree.
|
|
1101
|
-
* Aztec's version of `eth_getStorageAt`.
|
|
1102
|
-
*
|
|
1103
|
-
* @param contract - Address of the contract to query.
|
|
1104
|
-
* @param slot - Slot to query.
|
|
1105
|
-
* @param blockNumber - The block number at which to get the data or 'latest'.
|
|
1106
|
-
* @returns Storage value at the given contract slot.
|
|
1107
|
-
*/
|
|
1108
|
-
public async getPublicStorageAt(blockNumber: BlockParameter, contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
1109
|
-
const committedDb = await this.#getWorldState(blockNumber);
|
|
1066
|
+
public async getPublicStorageAt(referenceBlock: BlockParameter, contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
1067
|
+
const committedDb = await this.#getWorldState(referenceBlock);
|
|
1110
1068
|
const leafSlot = await computePublicDataTreeLeafSlot(contract, slot);
|
|
1111
1069
|
|
|
1112
1070
|
const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
@@ -1120,24 +1078,22 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1120
1078
|
return preimage.leaf.value;
|
|
1121
1079
|
}
|
|
1122
1080
|
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
public async getBlockHeaderByHash(blockHash: Fr): Promise<BlockHeader | undefined> {
|
|
1140
|
-
return await this.blockSource.getBlockHeaderByHash(blockHash);
|
|
1081
|
+
public async getBlockHeader(block: BlockParameter = 'latest'): Promise<BlockHeader | undefined> {
|
|
1082
|
+
if (BlockHash.isBlockHash(block)) {
|
|
1083
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
1084
|
+
if (block.equals(initialBlockHash)) {
|
|
1085
|
+
// Block source doesn't handle initial header so we need to handle the case separately.
|
|
1086
|
+
return this.worldStateSynchronizer.getCommitted().getInitialHeader();
|
|
1087
|
+
}
|
|
1088
|
+
return this.blockSource.getBlockHeaderByHash(block);
|
|
1089
|
+
} else {
|
|
1090
|
+
// Block source doesn't handle initial header so we need to handle the case separately.
|
|
1091
|
+
const blockNumber = block === 'latest' ? await this.getBlockNumber() : (block as BlockNumber);
|
|
1092
|
+
if (blockNumber === BlockNumber.ZERO) {
|
|
1093
|
+
return this.worldStateSynchronizer.getCommitted().getInitialHeader();
|
|
1094
|
+
}
|
|
1095
|
+
return this.blockSource.getBlockHeader(block);
|
|
1096
|
+
}
|
|
1141
1097
|
}
|
|
1142
1098
|
|
|
1143
1099
|
/**
|
|
@@ -1187,6 +1143,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1187
1143
|
this.contractDataSource,
|
|
1188
1144
|
new DateProvider(),
|
|
1189
1145
|
this.telemetry,
|
|
1146
|
+
this.log.getBindings(),
|
|
1190
1147
|
);
|
|
1191
1148
|
|
|
1192
1149
|
this.log.verbose(`Simulating public calls for tx ${txHash}`, {
|
|
@@ -1240,16 +1197,22 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1240
1197
|
// We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
|
|
1241
1198
|
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
1242
1199
|
const blockNumber = BlockNumber((await this.blockSource.getBlockNumber()) + 1);
|
|
1243
|
-
const validator = createValidatorForAcceptingTxs(
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1200
|
+
const validator = createValidatorForAcceptingTxs(
|
|
1201
|
+
db,
|
|
1202
|
+
this.contractDataSource,
|
|
1203
|
+
verifier,
|
|
1204
|
+
{
|
|
1205
|
+
timestamp: nextSlotTimestamp,
|
|
1206
|
+
blockNumber,
|
|
1207
|
+
l1ChainId: this.l1ChainId,
|
|
1208
|
+
rollupVersion: this.version,
|
|
1209
|
+
setupAllowList: this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions()),
|
|
1210
|
+
gasFees: await this.getCurrentMinFees(),
|
|
1211
|
+
skipFeeEnforcement,
|
|
1212
|
+
txsPermitted: !this.config.disableTransactions,
|
|
1213
|
+
},
|
|
1214
|
+
this.log.getBindings(),
|
|
1215
|
+
);
|
|
1253
1216
|
|
|
1254
1217
|
return await validator.validateTx(tx);
|
|
1255
1218
|
}
|
|
@@ -1318,7 +1281,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1318
1281
|
}
|
|
1319
1282
|
|
|
1320
1283
|
// And it has an L2 block hash
|
|
1321
|
-
const l2BlockHash = await archiver.getL2Tips().then(tips => tips.
|
|
1284
|
+
const l2BlockHash = await archiver.getL2Tips().then(tips => tips.proposed.hash);
|
|
1322
1285
|
if (!l2BlockHash) {
|
|
1323
1286
|
this.metrics.recordSnapshotError();
|
|
1324
1287
|
throw new Error(`Archiver has no latest L2 block hash downloaded. Cannot start snapshot.`);
|
|
@@ -1352,7 +1315,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1352
1315
|
throw new Error('Archiver implementation does not support rollbacks.');
|
|
1353
1316
|
}
|
|
1354
1317
|
|
|
1355
|
-
const finalizedBlock = await archiver.getL2Tips().then(tips => tips.finalized.number);
|
|
1318
|
+
const finalizedBlock = await archiver.getL2Tips().then(tips => tips.finalized.block.number);
|
|
1356
1319
|
if (targetBlock < finalizedBlock) {
|
|
1357
1320
|
if (force) {
|
|
1358
1321
|
this.log.warn(`Clearing world state database to allow rolling back behind finalized block ${finalizedBlock}`);
|
|
@@ -1413,16 +1376,19 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1413
1376
|
}
|
|
1414
1377
|
}
|
|
1415
1378
|
|
|
1379
|
+
#getInitialHeaderHash(): Promise<BlockHash> {
|
|
1380
|
+
if (!this.initialHeaderHashPromise) {
|
|
1381
|
+
this.initialHeaderHashPromise = this.worldStateSynchronizer.getCommitted().getInitialHeader().hash();
|
|
1382
|
+
}
|
|
1383
|
+
return this.initialHeaderHashPromise;
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1416
1386
|
/**
|
|
1417
1387
|
* Returns an instance of MerkleTreeOperations having first ensured the world state is fully synched
|
|
1418
|
-
* @param
|
|
1388
|
+
* @param block - The block parameter (block number, block hash, or 'latest') at which to get the data.
|
|
1419
1389
|
* @returns An instance of a committed MerkleTreeOperations
|
|
1420
1390
|
*/
|
|
1421
|
-
async #getWorldState(
|
|
1422
|
-
if (typeof blockNumber === 'number' && blockNumber < INITIAL_L2_BLOCK_NUM - 1) {
|
|
1423
|
-
throw new Error('Invalid block number to get world state for: ' + blockNumber);
|
|
1424
|
-
}
|
|
1425
|
-
|
|
1391
|
+
async #getWorldState(block: BlockParameter) {
|
|
1426
1392
|
let blockSyncedTo: BlockNumber = BlockNumber.ZERO;
|
|
1427
1393
|
try {
|
|
1428
1394
|
// Attempt to sync the world state if necessary
|
|
@@ -1431,15 +1397,39 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1431
1397
|
this.log.error(`Error getting world state: ${err}`);
|
|
1432
1398
|
}
|
|
1433
1399
|
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
this.log.debug(`Using committed db for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
|
|
1400
|
+
if (block === 'latest') {
|
|
1401
|
+
this.log.debug(`Using committed db for block 'latest', world state synced upto ${blockSyncedTo}`);
|
|
1437
1402
|
return this.worldStateSynchronizer.getCommitted();
|
|
1438
|
-
}
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
if (BlockHash.isBlockHash(block)) {
|
|
1406
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
1407
|
+
if (block.equals(initialBlockHash)) {
|
|
1408
|
+
// Block source doesn't handle initial header so we need to handle the case separately.
|
|
1409
|
+
return this.worldStateSynchronizer.getSnapshot(BlockNumber.ZERO);
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
const header = await this.blockSource.getBlockHeaderByHash(block);
|
|
1413
|
+
if (!header) {
|
|
1414
|
+
throw new Error(
|
|
1415
|
+
`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.`,
|
|
1416
|
+
);
|
|
1417
|
+
}
|
|
1418
|
+
const blockNumber = header.getBlockNumber();
|
|
1439
1419
|
this.log.debug(`Using snapshot for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
|
|
1440
|
-
return this.worldStateSynchronizer.getSnapshot(blockNumber
|
|
1441
|
-
}
|
|
1442
|
-
|
|
1420
|
+
return this.worldStateSynchronizer.getSnapshot(blockNumber);
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
// Block number provided
|
|
1424
|
+
{
|
|
1425
|
+
const blockNumber = block as BlockNumber;
|
|
1426
|
+
|
|
1427
|
+
if (blockNumber > blockSyncedTo) {
|
|
1428
|
+
throw new Error(`Queried block ${block} not yet synced by the node (node is synced upto ${blockSyncedTo}).`);
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
this.log.debug(`Using snapshot for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
|
|
1432
|
+
return this.worldStateSynchronizer.getSnapshot(blockNumber);
|
|
1443
1433
|
}
|
|
1444
1434
|
}
|
|
1445
1435
|
|