@aztec/aztec-node 0.0.1-commit.fcb71a6 → 0.0.1-commit.fffb133c
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 +5 -16
- package/dest/aztec-node/server.d.ts +40 -96
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +579 -173
- 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 +5 -23
- package/src/aztec-node/server.ts +227 -203
- package/src/sentinel/sentinel.ts +41 -32
package/src/aztec-node/server.ts
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
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';
|
|
3
|
+
import { type BlobClientInterface, createBlobClientWithFileStores } from '@aztec/blob-client/client';
|
|
9
4
|
import {
|
|
10
5
|
ARCHIVE_HEIGHT,
|
|
11
|
-
INITIAL_L2_BLOCK_NUM,
|
|
12
6
|
type L1_TO_L2_MSG_TREE_HEIGHT,
|
|
13
7
|
type NOTE_HASH_TREE_HEIGHT,
|
|
14
8
|
type NULLIFIER_TREE_HEIGHT,
|
|
@@ -19,7 +13,7 @@ import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
|
19
13
|
import { getPublicClient } from '@aztec/ethereum/client';
|
|
20
14
|
import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
21
15
|
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
22
|
-
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
16
|
+
import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
23
17
|
import { compactArray, pick } from '@aztec/foundation/collection';
|
|
24
18
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
25
19
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
@@ -36,14 +30,7 @@ import {
|
|
|
36
30
|
} from '@aztec/node-lib/factories';
|
|
37
31
|
import { type P2P, type P2PClientDeps, createP2PClient, getDefaultAllowedSetupFunctions } from '@aztec/p2p';
|
|
38
32
|
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';
|
|
33
|
+
import { GlobalVariableBuilder, SequencerClient, type SequencerPublisher } from '@aztec/sequencer-client';
|
|
47
34
|
import { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
48
35
|
import {
|
|
49
36
|
AttestationsBlockWatcher,
|
|
@@ -54,14 +41,8 @@ import {
|
|
|
54
41
|
} from '@aztec/slasher';
|
|
55
42
|
import { CollectionLimitsConfig, PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
56
43
|
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';
|
|
44
|
+
import { type BlockParameter, type DataInBlock, L2Block, L2BlockHash, type L2BlockSource } from '@aztec/stdlib/block';
|
|
45
|
+
import type { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
65
46
|
import type {
|
|
66
47
|
ContractClassPublic,
|
|
67
48
|
ContractDataSource,
|
|
@@ -116,10 +97,13 @@ import {
|
|
|
116
97
|
trackSpan,
|
|
117
98
|
} from '@aztec/telemetry-client';
|
|
118
99
|
import {
|
|
100
|
+
FullNodeCheckpointsBuilder as CheckpointsBuilder,
|
|
101
|
+
FullNodeCheckpointsBuilder,
|
|
119
102
|
NodeKeystoreAdapter,
|
|
120
103
|
ValidatorClient,
|
|
121
104
|
createBlockProposalHandler,
|
|
122
105
|
createValidatorClient,
|
|
106
|
+
createValidatorForAcceptingTxs,
|
|
123
107
|
} from '@aztec/validator-client';
|
|
124
108
|
import { createWorldStateSynchronizer } from '@aztec/world-state';
|
|
125
109
|
|
|
@@ -135,6 +119,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
135
119
|
*/
|
|
136
120
|
export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
137
121
|
private metrics: NodeMetrics;
|
|
122
|
+
private initialHeaderHashPromise: Promise<L2BlockHash> | undefined = undefined;
|
|
138
123
|
|
|
139
124
|
// Prevent two snapshot operations to happen simultaneously
|
|
140
125
|
private isUploadingSnapshot = false;
|
|
@@ -191,7 +176,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
191
176
|
logger?: Logger;
|
|
192
177
|
publisher?: SequencerPublisher;
|
|
193
178
|
dateProvider?: DateProvider;
|
|
194
|
-
blobClient?: BlobClientInterface;
|
|
195
179
|
p2pClientDeps?: P2PClientDeps<P2PClientType.Full>;
|
|
196
180
|
} = {},
|
|
197
181
|
options: {
|
|
@@ -271,24 +255,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
271
255
|
);
|
|
272
256
|
}
|
|
273
257
|
|
|
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
|
-
});
|
|
258
|
+
const blobClient = await createBlobClientWithFileStores(config, createLogger('node:blob-client:client'));
|
|
292
259
|
|
|
293
260
|
// attempt snapshot sync if possible
|
|
294
261
|
await trySnapshotSync(config, log);
|
|
@@ -334,7 +301,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
334
301
|
// We should really not be modifying the config object
|
|
335
302
|
config.txPublicSetupAllowList = config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
|
|
336
303
|
|
|
337
|
-
|
|
304
|
+
// Create FullNodeCheckpointsBuilder for validator and non-validator block proposal handling
|
|
305
|
+
const validatorCheckpointsBuilder = new FullNodeCheckpointsBuilder(
|
|
338
306
|
{ ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
|
|
339
307
|
worldStateSynchronizer,
|
|
340
308
|
archiver,
|
|
@@ -346,16 +314,17 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
346
314
|
const watchers: Watcher[] = [];
|
|
347
315
|
|
|
348
316
|
// Create validator client if required
|
|
349
|
-
const validatorClient = createValidatorClient(config, {
|
|
317
|
+
const validatorClient = await createValidatorClient(config, {
|
|
318
|
+
checkpointsBuilder: validatorCheckpointsBuilder,
|
|
319
|
+
worldState: worldStateSynchronizer,
|
|
350
320
|
p2pClient,
|
|
351
321
|
telemetry,
|
|
352
322
|
dateProvider,
|
|
353
323
|
epochCache,
|
|
354
|
-
blockBuilder,
|
|
355
324
|
blockSource: archiver,
|
|
356
325
|
l1ToL2MessageSource: archiver,
|
|
357
326
|
keyStoreManager,
|
|
358
|
-
|
|
327
|
+
blobClient,
|
|
359
328
|
});
|
|
360
329
|
|
|
361
330
|
// If we have a validator client, register it as a source of offenses for the slasher,
|
|
@@ -373,7 +342,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
373
342
|
if (!validatorClient && config.alwaysReexecuteBlockProposals) {
|
|
374
343
|
log.info('Setting up block proposal reexecution for monitoring');
|
|
375
344
|
createBlockProposalHandler(config, {
|
|
376
|
-
|
|
345
|
+
checkpointsBuilder: validatorCheckpointsBuilder,
|
|
346
|
+
worldState: worldStateSynchronizer,
|
|
377
347
|
epochCache,
|
|
378
348
|
blockSource: archiver,
|
|
379
349
|
l1ToL2MessageSource: archiver,
|
|
@@ -401,7 +371,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
401
371
|
archiver,
|
|
402
372
|
epochCache,
|
|
403
373
|
p2pClient.getTxProvider(),
|
|
404
|
-
|
|
374
|
+
validatorCheckpointsBuilder,
|
|
405
375
|
config,
|
|
406
376
|
);
|
|
407
377
|
watchers.push(epochPruneWatcher);
|
|
@@ -466,6 +436,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
466
436
|
// Create and start the sequencer client
|
|
467
437
|
const checkpointsBuilder = new CheckpointsBuilder(
|
|
468
438
|
{ ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
|
|
439
|
+
worldStateSynchronizer,
|
|
469
440
|
archiver,
|
|
470
441
|
dateProvider,
|
|
471
442
|
telemetry,
|
|
@@ -594,13 +565,19 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
594
565
|
}
|
|
595
566
|
|
|
596
567
|
/**
|
|
597
|
-
* Get a block specified by its number.
|
|
598
|
-
* @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').
|
|
599
570
|
* @returns The requested block.
|
|
600
571
|
*/
|
|
601
|
-
public async getBlock(
|
|
602
|
-
|
|
603
|
-
|
|
572
|
+
public async getBlock(block: BlockParameter): Promise<L2Block | undefined> {
|
|
573
|
+
if (L2BlockHash.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);
|
|
604
581
|
}
|
|
605
582
|
|
|
606
583
|
/**
|
|
@@ -609,8 +586,16 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
609
586
|
* @returns The requested block.
|
|
610
587
|
*/
|
|
611
588
|
public async getBlockByHash(blockHash: Fr): Promise<L2Block | undefined> {
|
|
612
|
-
const
|
|
613
|
-
|
|
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);
|
|
614
599
|
}
|
|
615
600
|
|
|
616
601
|
/**
|
|
@@ -619,8 +604,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
619
604
|
* @returns The requested block.
|
|
620
605
|
*/
|
|
621
606
|
public async getBlockByArchive(archive: Fr): Promise<L2Block | undefined> {
|
|
622
|
-
|
|
623
|
-
return publishedBlock?.block;
|
|
607
|
+
return await this.blockSource.getL2BlockByArchive(archive);
|
|
624
608
|
}
|
|
625
609
|
|
|
626
610
|
/**
|
|
@@ -630,19 +614,23 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
630
614
|
* @returns The blocks requested.
|
|
631
615
|
*/
|
|
632
616
|
public async getBlocks(from: BlockNumber, limit: number): Promise<L2Block[]> {
|
|
633
|
-
return (await this.blockSource.getBlocks(from, limit)) ?? [];
|
|
617
|
+
return (await this.blockSource.getBlocks(from, BlockNumber(limit))) ?? [];
|
|
634
618
|
}
|
|
635
619
|
|
|
636
|
-
public async
|
|
637
|
-
return (await this.blockSource.
|
|
620
|
+
public async getCheckpoints(from: CheckpointNumber, limit: number): Promise<PublishedCheckpoint[]> {
|
|
621
|
+
return (await this.blockSource.getCheckpoints(from, limit)) ?? [];
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
public async getCheckpointedBlocks(from: BlockNumber, limit: number) {
|
|
625
|
+
return (await this.blockSource.getCheckpointedBlocks(from, limit)) ?? [];
|
|
638
626
|
}
|
|
639
627
|
|
|
640
628
|
/**
|
|
641
|
-
* Method to fetch the current
|
|
642
|
-
* @returns The current
|
|
629
|
+
* Method to fetch the current min L2 fees.
|
|
630
|
+
* @returns The current min L2 fees.
|
|
643
631
|
*/
|
|
644
|
-
public async
|
|
645
|
-
return await this.globalVariableBuilder.
|
|
632
|
+
public async getCurrentMinFees(): Promise<GasFees> {
|
|
633
|
+
return await this.globalVariableBuilder.getCurrentMinFees();
|
|
646
634
|
}
|
|
647
635
|
|
|
648
636
|
public async getMaxPriorityFees(): Promise<GasFees> {
|
|
@@ -665,6 +653,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
665
653
|
return await this.blockSource.getProvenBlockNumber();
|
|
666
654
|
}
|
|
667
655
|
|
|
656
|
+
public async getCheckpointedBlockNumber(): Promise<BlockNumber> {
|
|
657
|
+
return await this.blockSource.getCheckpointedL2BlockNumber();
|
|
658
|
+
}
|
|
659
|
+
|
|
668
660
|
/**
|
|
669
661
|
* Method to fetch the version of the package.
|
|
670
662
|
* @returns The node package version
|
|
@@ -697,12 +689,45 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
697
689
|
return this.contractDataSource.getContract(address);
|
|
698
690
|
}
|
|
699
691
|
|
|
700
|
-
public getPrivateLogsByTags(
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
692
|
+
public async getPrivateLogsByTags(
|
|
693
|
+
tags: SiloedTag[],
|
|
694
|
+
page?: number,
|
|
695
|
+
referenceBlock?: L2BlockHash,
|
|
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?: L2BlockHash,
|
|
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);
|
|
706
731
|
}
|
|
707
732
|
|
|
708
733
|
/**
|
|
@@ -749,21 +774,26 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
749
774
|
}
|
|
750
775
|
|
|
751
776
|
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
|
-
}
|
|
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';
|
|
760
781
|
|
|
782
|
+
// Then get the actual tx from the archiver, which tracks every tx in a mined block.
|
|
761
783
|
const settledTxReceipt = await this.blockSource.getSettledTxReceipt(txHash);
|
|
784
|
+
|
|
762
785
|
if (settledTxReceipt) {
|
|
763
|
-
|
|
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');
|
|
764
796
|
}
|
|
765
|
-
|
|
766
|
-
return txReceipt;
|
|
767
797
|
}
|
|
768
798
|
|
|
769
799
|
public getTxEffect(txHash: TxHash): Promise<IndexedTxEffect | undefined> {
|
|
@@ -788,6 +818,14 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
788
818
|
this.log.info(`Stopped Aztec Node`);
|
|
789
819
|
}
|
|
790
820
|
|
|
821
|
+
/**
|
|
822
|
+
* Returns the blob client used by this node.
|
|
823
|
+
* @internal - Exposed for testing purposes only.
|
|
824
|
+
*/
|
|
825
|
+
public getBlobClient(): BlobClientInterface | undefined {
|
|
826
|
+
return this.blobClient;
|
|
827
|
+
}
|
|
828
|
+
|
|
791
829
|
/**
|
|
792
830
|
* Method to retrieve pending txs.
|
|
793
831
|
* @param limit - The number of items to returns
|
|
@@ -820,20 +858,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
820
858
|
return compactArray(await Promise.all(txHashes.map(txHash => this.getTxByHash(txHash))));
|
|
821
859
|
}
|
|
822
860
|
|
|
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
861
|
public async findLeavesIndexes(
|
|
832
|
-
|
|
862
|
+
block: BlockParameter,
|
|
833
863
|
treeId: MerkleTreeId,
|
|
834
864
|
leafValues: Fr[],
|
|
835
865
|
): Promise<(DataInBlock<bigint> | undefined)[]> {
|
|
836
|
-
const committedDb = await this.#getWorldState(
|
|
866
|
+
const committedDb = await this.#getWorldState(block);
|
|
837
867
|
const maybeIndices = await committedDb.findLeafIndices(
|
|
838
868
|
treeId,
|
|
839
869
|
leafValues.map(x => x.toBuffer()),
|
|
@@ -891,39 +921,27 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
891
921
|
});
|
|
892
922
|
}
|
|
893
923
|
|
|
894
|
-
/**
|
|
895
|
-
* Returns a sibling path for the given index in the nullifier tree.
|
|
896
|
-
* @param blockNumber - The block number at which to get the data.
|
|
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
924
|
public async getNullifierSiblingPath(
|
|
901
|
-
|
|
925
|
+
block: BlockParameter,
|
|
902
926
|
leafIndex: bigint,
|
|
903
927
|
): Promise<SiblingPath<typeof NULLIFIER_TREE_HEIGHT>> {
|
|
904
|
-
const committedDb = await this.#getWorldState(
|
|
928
|
+
const committedDb = await this.#getWorldState(block);
|
|
905
929
|
return committedDb.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, leafIndex);
|
|
906
930
|
}
|
|
907
931
|
|
|
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
932
|
public async getNoteHashSiblingPath(
|
|
915
|
-
|
|
933
|
+
block: BlockParameter,
|
|
916
934
|
leafIndex: bigint,
|
|
917
935
|
): Promise<SiblingPath<typeof NOTE_HASH_TREE_HEIGHT>> {
|
|
918
|
-
const committedDb = await this.#getWorldState(
|
|
936
|
+
const committedDb = await this.#getWorldState(block);
|
|
919
937
|
return committedDb.getSiblingPath(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
|
|
920
938
|
}
|
|
921
939
|
|
|
922
940
|
public async getArchiveMembershipWitness(
|
|
923
|
-
|
|
941
|
+
block: BlockParameter,
|
|
924
942
|
archive: Fr,
|
|
925
943
|
): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined> {
|
|
926
|
-
const committedDb = await this.#getWorldState(
|
|
944
|
+
const committedDb = await this.#getWorldState(block);
|
|
927
945
|
const [pathAndIndex] = await committedDb.findSiblingPaths<MerkleTreeId.ARCHIVE>(MerkleTreeId.ARCHIVE, [archive]);
|
|
928
946
|
return pathAndIndex === undefined
|
|
929
947
|
? undefined
|
|
@@ -931,10 +949,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
931
949
|
}
|
|
932
950
|
|
|
933
951
|
public async getNoteHashMembershipWitness(
|
|
934
|
-
|
|
952
|
+
block: BlockParameter,
|
|
935
953
|
noteHash: Fr,
|
|
936
954
|
): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
|
|
937
|
-
const committedDb = await this.#getWorldState(
|
|
955
|
+
const committedDb = await this.#getWorldState(block);
|
|
938
956
|
const [pathAndIndex] = await committedDb.findSiblingPaths<MerkleTreeId.NOTE_HASH_TREE>(
|
|
939
957
|
MerkleTreeId.NOTE_HASH_TREE,
|
|
940
958
|
[noteHash],
|
|
@@ -944,17 +962,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
944
962
|
: MembershipWitness.fromSiblingPath(pathAndIndex.index, pathAndIndex.path);
|
|
945
963
|
}
|
|
946
964
|
|
|
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
965
|
public async getL1ToL2MessageMembershipWitness(
|
|
954
|
-
|
|
966
|
+
block: BlockParameter,
|
|
955
967
|
l1ToL2Message: Fr,
|
|
956
968
|
): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>] | undefined> {
|
|
957
|
-
const db = await this.#getWorldState(
|
|
969
|
+
const db = await this.#getWorldState(block);
|
|
958
970
|
const [witness] = await db.findSiblingPaths(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, [l1ToL2Message]);
|
|
959
971
|
if (!witness) {
|
|
960
972
|
return undefined;
|
|
@@ -982,56 +994,52 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
982
994
|
}
|
|
983
995
|
|
|
984
996
|
/**
|
|
985
|
-
* Returns all the L2 to L1 messages in
|
|
986
|
-
* @param
|
|
987
|
-
* @returns The L2 to L1 messages (
|
|
997
|
+
* Returns all the L2 to L1 messages in an epoch.
|
|
998
|
+
* @param epoch - The epoch at which to get the data.
|
|
999
|
+
* @returns The L2 to L1 messages (empty array if the epoch is not found).
|
|
988
1000
|
*/
|
|
989
|
-
public async getL2ToL1Messages(
|
|
990
|
-
|
|
991
|
-
|
|
1001
|
+
public async getL2ToL1Messages(epoch: EpochNumber): Promise<Fr[][][][]> {
|
|
1002
|
+
// Assumes `getCheckpointedBlocksForEpoch` returns blocks in ascending order of block number.
|
|
1003
|
+
const checkpointedBlocks = await this.blockSource.getCheckpointedBlocksForEpoch(epoch);
|
|
1004
|
+
const blocksInCheckpoints: L2Block[][] = [];
|
|
1005
|
+
let previousSlotNumber = SlotNumber.ZERO;
|
|
1006
|
+
let checkpointIndex = -1;
|
|
1007
|
+
for (const checkpointedBlock of checkpointedBlocks) {
|
|
1008
|
+
const block = checkpointedBlock.block;
|
|
1009
|
+
const slotNumber = block.header.globalVariables.slotNumber;
|
|
1010
|
+
if (slotNumber !== previousSlotNumber) {
|
|
1011
|
+
checkpointIndex++;
|
|
1012
|
+
blocksInCheckpoints.push([]);
|
|
1013
|
+
previousSlotNumber = slotNumber;
|
|
1014
|
+
}
|
|
1015
|
+
blocksInCheckpoints[checkpointIndex].push(block);
|
|
1016
|
+
}
|
|
1017
|
+
return blocksInCheckpoints.map(blocks =>
|
|
1018
|
+
blocks.map(block => block.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs)),
|
|
992
1019
|
);
|
|
993
|
-
return block?.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs);
|
|
994
1020
|
}
|
|
995
1021
|
|
|
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
1022
|
public async getArchiveSiblingPath(
|
|
1003
|
-
|
|
1023
|
+
block: BlockParameter,
|
|
1004
1024
|
leafIndex: bigint,
|
|
1005
1025
|
): Promise<SiblingPath<typeof ARCHIVE_HEIGHT>> {
|
|
1006
|
-
const committedDb = await this.#getWorldState(
|
|
1026
|
+
const committedDb = await this.#getWorldState(block);
|
|
1007
1027
|
return committedDb.getSiblingPath(MerkleTreeId.ARCHIVE, leafIndex);
|
|
1008
1028
|
}
|
|
1009
1029
|
|
|
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
1030
|
public async getPublicDataSiblingPath(
|
|
1017
|
-
|
|
1031
|
+
block: BlockParameter,
|
|
1018
1032
|
leafIndex: bigint,
|
|
1019
1033
|
): Promise<SiblingPath<typeof PUBLIC_DATA_TREE_HEIGHT>> {
|
|
1020
|
-
const committedDb = await this.#getWorldState(
|
|
1034
|
+
const committedDb = await this.#getWorldState(block);
|
|
1021
1035
|
return committedDb.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, leafIndex);
|
|
1022
1036
|
}
|
|
1023
1037
|
|
|
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
1038
|
public async getNullifierMembershipWitness(
|
|
1031
|
-
|
|
1039
|
+
block: BlockParameter,
|
|
1032
1040
|
nullifier: Fr,
|
|
1033
1041
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
1034
|
-
const db = await this.#getWorldState(
|
|
1042
|
+
const db = await this.#getWorldState(block);
|
|
1035
1043
|
const [witness] = await db.findSiblingPaths(MerkleTreeId.NULLIFIER_TREE, [nullifier.toBuffer()]);
|
|
1036
1044
|
if (!witness) {
|
|
1037
1045
|
return undefined;
|
|
@@ -1048,7 +1056,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1048
1056
|
|
|
1049
1057
|
/**
|
|
1050
1058
|
* Returns a low nullifier membership witness for a given nullifier at a given block.
|
|
1051
|
-
* @param
|
|
1059
|
+
* @param block - The block parameter (block number, block hash, or 'latest') at which to get the data.
|
|
1052
1060
|
* @param nullifier - Nullifier we try to find the low nullifier witness for.
|
|
1053
1061
|
* @returns The low nullifier membership witness (if found).
|
|
1054
1062
|
* @remarks Low nullifier witness can be used to perform a nullifier non-inclusion proof by leveraging the "linked
|
|
@@ -1061,10 +1069,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1061
1069
|
* TODO: This is a confusing behavior and we should eventually address that.
|
|
1062
1070
|
*/
|
|
1063
1071
|
public async getLowNullifierMembershipWitness(
|
|
1064
|
-
|
|
1072
|
+
block: BlockParameter,
|
|
1065
1073
|
nullifier: Fr,
|
|
1066
1074
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
1067
|
-
const committedDb = await this.#getWorldState(
|
|
1075
|
+
const committedDb = await this.#getWorldState(block);
|
|
1068
1076
|
const findResult = await committedDb.getPreviousValueIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBigInt());
|
|
1069
1077
|
if (!findResult) {
|
|
1070
1078
|
return undefined;
|
|
@@ -1079,8 +1087,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1079
1087
|
return new NullifierMembershipWitness(BigInt(index), preimageData as NullifierLeafPreimage, siblingPath);
|
|
1080
1088
|
}
|
|
1081
1089
|
|
|
1082
|
-
async getPublicDataWitness(
|
|
1083
|
-
const committedDb = await this.#getWorldState(
|
|
1090
|
+
async getPublicDataWitness(block: BlockParameter, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
|
|
1091
|
+
const committedDb = await this.#getWorldState(block);
|
|
1084
1092
|
const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
1085
1093
|
if (!lowLeafResult) {
|
|
1086
1094
|
return undefined;
|
|
@@ -1094,19 +1102,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1094
1102
|
}
|
|
1095
1103
|
}
|
|
1096
1104
|
|
|
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);
|
|
1105
|
+
public async getPublicStorageAt(block: BlockParameter, contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
1106
|
+
const committedDb = await this.#getWorldState(block);
|
|
1110
1107
|
const leafSlot = await computePublicDataTreeLeafSlot(contract, slot);
|
|
1111
1108
|
|
|
1112
1109
|
const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
@@ -1120,24 +1117,23 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1120
1117
|
return preimage.leaf.value;
|
|
1121
1118
|
}
|
|
1122
1119
|
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
return await this.blockSource.getBlockHeaderByHash(blockHash);
|
|
1120
|
+
public async getBlockHeader(block: BlockParameter = 'latest'): Promise<BlockHeader | undefined> {
|
|
1121
|
+
if (L2BlockHash.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
|
+
}
|
|
1141
1137
|
}
|
|
1142
1138
|
|
|
1143
1139
|
/**
|
|
@@ -1246,7 +1242,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1246
1242
|
l1ChainId: this.l1ChainId,
|
|
1247
1243
|
rollupVersion: this.version,
|
|
1248
1244
|
setupAllowList: this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions()),
|
|
1249
|
-
gasFees: await this.
|
|
1245
|
+
gasFees: await this.getCurrentMinFees(),
|
|
1250
1246
|
skipFeeEnforcement,
|
|
1251
1247
|
txsPermitted: !this.config.disableTransactions,
|
|
1252
1248
|
});
|
|
@@ -1318,7 +1314,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1318
1314
|
}
|
|
1319
1315
|
|
|
1320
1316
|
// And it has an L2 block hash
|
|
1321
|
-
const l2BlockHash = await archiver.getL2Tips().then(tips => tips.
|
|
1317
|
+
const l2BlockHash = await archiver.getL2Tips().then(tips => tips.proposed.hash);
|
|
1322
1318
|
if (!l2BlockHash) {
|
|
1323
1319
|
this.metrics.recordSnapshotError();
|
|
1324
1320
|
throw new Error(`Archiver has no latest L2 block hash downloaded. Cannot start snapshot.`);
|
|
@@ -1352,7 +1348,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1352
1348
|
throw new Error('Archiver implementation does not support rollbacks.');
|
|
1353
1349
|
}
|
|
1354
1350
|
|
|
1355
|
-
const finalizedBlock = await archiver.getL2Tips().then(tips => tips.finalized.number);
|
|
1351
|
+
const finalizedBlock = await archiver.getL2Tips().then(tips => tips.finalized.block.number);
|
|
1356
1352
|
if (targetBlock < finalizedBlock) {
|
|
1357
1353
|
if (force) {
|
|
1358
1354
|
this.log.warn(`Clearing world state database to allow rolling back behind finalized block ${finalizedBlock}`);
|
|
@@ -1413,16 +1409,19 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1413
1409
|
}
|
|
1414
1410
|
}
|
|
1415
1411
|
|
|
1412
|
+
#getInitialHeaderHash(): Promise<L2BlockHash> {
|
|
1413
|
+
if (!this.initialHeaderHashPromise) {
|
|
1414
|
+
this.initialHeaderHashPromise = this.worldStateSynchronizer.getCommitted().getInitialHeader().hash();
|
|
1415
|
+
}
|
|
1416
|
+
return this.initialHeaderHashPromise;
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1416
1419
|
/**
|
|
1417
1420
|
* Returns an instance of MerkleTreeOperations having first ensured the world state is fully synched
|
|
1418
|
-
* @param
|
|
1421
|
+
* @param block - The block parameter (block number, block hash, or 'latest') at which to get the data.
|
|
1419
1422
|
* @returns An instance of a committed MerkleTreeOperations
|
|
1420
1423
|
*/
|
|
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
|
-
|
|
1424
|
+
async #getWorldState(block: BlockParameter) {
|
|
1426
1425
|
let blockSyncedTo: BlockNumber = BlockNumber.ZERO;
|
|
1427
1426
|
try {
|
|
1428
1427
|
// Attempt to sync the world state if necessary
|
|
@@ -1431,15 +1430,40 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1431
1430
|
this.log.error(`Error getting world state: ${err}`);
|
|
1432
1431
|
}
|
|
1433
1432
|
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
this.log.debug(`Using committed db for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
|
|
1433
|
+
if (block === 'latest') {
|
|
1434
|
+
this.log.debug(`Using committed db for block 'latest', world state synced upto ${blockSyncedTo}`);
|
|
1437
1435
|
return this.worldStateSynchronizer.getCommitted();
|
|
1438
|
-
}
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
if (L2BlockHash.isL2BlockHash(block)) {
|
|
1439
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
1440
|
+
if (block.equals(initialBlockHash)) {
|
|
1441
|
+
// Block source doesn't handle initial header so we need to handle the case separately.
|
|
1442
|
+
return this.worldStateSynchronizer.getSnapshot(BlockNumber.ZERO);
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
const blockHashFr = Fr.fromBuffer(block.toBuffer());
|
|
1446
|
+
const header = await this.blockSource.getBlockHeaderByHash(blockHashFr);
|
|
1447
|
+
if (!header) {
|
|
1448
|
+
throw new Error(
|
|
1449
|
+
`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.`,
|
|
1450
|
+
);
|
|
1451
|
+
}
|
|
1452
|
+
const blockNumber = header.getBlockNumber();
|
|
1439
1453
|
this.log.debug(`Using snapshot for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
|
|
1440
|
-
return this.worldStateSynchronizer.getSnapshot(blockNumber
|
|
1441
|
-
}
|
|
1442
|
-
|
|
1454
|
+
return this.worldStateSynchronizer.getSnapshot(blockNumber);
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
// Block number provided
|
|
1458
|
+
{
|
|
1459
|
+
const blockNumber = block as BlockNumber;
|
|
1460
|
+
|
|
1461
|
+
if (blockNumber > blockSyncedTo) {
|
|
1462
|
+
throw new Error(`Queried block ${block} not yet synced by the node (node is synced upto ${blockSyncedTo}).`);
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
this.log.debug(`Using snapshot for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
|
|
1466
|
+
return this.worldStateSynchronizer.getSnapshot(blockNumber);
|
|
1443
1467
|
}
|
|
1444
1468
|
}
|
|
1445
1469
|
|