@aztec/aztec-node 0.0.1-commit.03f7ef2 → 0.0.1-commit.0b941701
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 +42 -97
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +584 -175
- 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 +230 -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;
|
|
@@ -161,6 +146,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
161
146
|
private proofVerifier: ClientProtocolCircuitVerifier,
|
|
162
147
|
private telemetry: TelemetryClient = getTelemetryClient(),
|
|
163
148
|
private log = createLogger('node'),
|
|
149
|
+
private blobClient?: BlobClientInterface,
|
|
164
150
|
) {
|
|
165
151
|
this.metrics = new NodeMetrics(telemetry, 'AztecNodeService');
|
|
166
152
|
this.tracer = telemetry.getTracer('AztecNodeService');
|
|
@@ -190,7 +176,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
190
176
|
logger?: Logger;
|
|
191
177
|
publisher?: SequencerPublisher;
|
|
192
178
|
dateProvider?: DateProvider;
|
|
193
|
-
blobClient?: BlobClientInterface;
|
|
194
179
|
p2pClientDeps?: P2PClientDeps<P2PClientType.Full>;
|
|
195
180
|
} = {},
|
|
196
181
|
options: {
|
|
@@ -270,24 +255,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
270
255
|
);
|
|
271
256
|
}
|
|
272
257
|
|
|
273
|
-
const
|
|
274
|
-
l1ChainId: config.l1ChainId,
|
|
275
|
-
rollupVersion: config.rollupVersion,
|
|
276
|
-
rollupAddress: config.l1Contracts.rollupAddress.toString(),
|
|
277
|
-
};
|
|
278
|
-
|
|
279
|
-
const [fileStoreClients, fileStoreUploadClient] = await Promise.all([
|
|
280
|
-
createReadOnlyFileStoreBlobClients(config.blobFileStoreUrls, blobFileStoreMetadata, log),
|
|
281
|
-
createWritableFileStoreBlobClient(config.blobFileStoreUploadUrl, blobFileStoreMetadata, log),
|
|
282
|
-
]);
|
|
283
|
-
|
|
284
|
-
const blobClient =
|
|
285
|
-
deps.blobClient ??
|
|
286
|
-
createBlobClient(config, {
|
|
287
|
-
logger: createLogger('node:blob-client:client'),
|
|
288
|
-
fileStoreClients,
|
|
289
|
-
fileStoreUploadClient,
|
|
290
|
-
});
|
|
258
|
+
const blobClient = await createBlobClientWithFileStores(config, createLogger('node:blob-client:client'));
|
|
291
259
|
|
|
292
260
|
// attempt snapshot sync if possible
|
|
293
261
|
await trySnapshotSync(config, log);
|
|
@@ -333,7 +301,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
333
301
|
// We should really not be modifying the config object
|
|
334
302
|
config.txPublicSetupAllowList = config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
|
|
335
303
|
|
|
336
|
-
|
|
304
|
+
// Create FullNodeCheckpointsBuilder for validator and non-validator block proposal handling
|
|
305
|
+
const validatorCheckpointsBuilder = new FullNodeCheckpointsBuilder(
|
|
337
306
|
{ ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
|
|
338
307
|
worldStateSynchronizer,
|
|
339
308
|
archiver,
|
|
@@ -345,16 +314,17 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
345
314
|
const watchers: Watcher[] = [];
|
|
346
315
|
|
|
347
316
|
// Create validator client if required
|
|
348
|
-
const validatorClient = createValidatorClient(config, {
|
|
317
|
+
const validatorClient = await createValidatorClient(config, {
|
|
318
|
+
checkpointsBuilder: validatorCheckpointsBuilder,
|
|
319
|
+
worldState: worldStateSynchronizer,
|
|
349
320
|
p2pClient,
|
|
350
321
|
telemetry,
|
|
351
322
|
dateProvider,
|
|
352
323
|
epochCache,
|
|
353
|
-
blockBuilder,
|
|
354
324
|
blockSource: archiver,
|
|
355
325
|
l1ToL2MessageSource: archiver,
|
|
356
326
|
keyStoreManager,
|
|
357
|
-
|
|
327
|
+
blobClient,
|
|
358
328
|
});
|
|
359
329
|
|
|
360
330
|
// If we have a validator client, register it as a source of offenses for the slasher,
|
|
@@ -372,7 +342,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
372
342
|
if (!validatorClient && config.alwaysReexecuteBlockProposals) {
|
|
373
343
|
log.info('Setting up block proposal reexecution for monitoring');
|
|
374
344
|
createBlockProposalHandler(config, {
|
|
375
|
-
|
|
345
|
+
checkpointsBuilder: validatorCheckpointsBuilder,
|
|
346
|
+
worldState: worldStateSynchronizer,
|
|
376
347
|
epochCache,
|
|
377
348
|
blockSource: archiver,
|
|
378
349
|
l1ToL2MessageSource: archiver,
|
|
@@ -400,7 +371,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
400
371
|
archiver,
|
|
401
372
|
epochCache,
|
|
402
373
|
p2pClient.getTxProvider(),
|
|
403
|
-
|
|
374
|
+
validatorCheckpointsBuilder,
|
|
404
375
|
config,
|
|
405
376
|
);
|
|
406
377
|
watchers.push(epochPruneWatcher);
|
|
@@ -465,6 +436,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
465
436
|
// Create and start the sequencer client
|
|
466
437
|
const checkpointsBuilder = new CheckpointsBuilder(
|
|
467
438
|
{ ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
|
|
439
|
+
worldStateSynchronizer,
|
|
468
440
|
archiver,
|
|
469
441
|
dateProvider,
|
|
470
442
|
telemetry,
|
|
@@ -522,6 +494,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
522
494
|
proofVerifier,
|
|
523
495
|
telemetry,
|
|
524
496
|
log,
|
|
497
|
+
blobClient,
|
|
525
498
|
);
|
|
526
499
|
}
|
|
527
500
|
|
|
@@ -592,13 +565,19 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
592
565
|
}
|
|
593
566
|
|
|
594
567
|
/**
|
|
595
|
-
* Get a block specified by its number.
|
|
596
|
-
* @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').
|
|
597
570
|
* @returns The requested block.
|
|
598
571
|
*/
|
|
599
|
-
public async getBlock(
|
|
600
|
-
|
|
601
|
-
|
|
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);
|
|
602
581
|
}
|
|
603
582
|
|
|
604
583
|
/**
|
|
@@ -607,8 +586,16 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
607
586
|
* @returns The requested block.
|
|
608
587
|
*/
|
|
609
588
|
public async getBlockByHash(blockHash: Fr): Promise<L2Block | undefined> {
|
|
610
|
-
const
|
|
611
|
-
|
|
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);
|
|
612
599
|
}
|
|
613
600
|
|
|
614
601
|
/**
|
|
@@ -617,8 +604,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
617
604
|
* @returns The requested block.
|
|
618
605
|
*/
|
|
619
606
|
public async getBlockByArchive(archive: Fr): Promise<L2Block | undefined> {
|
|
620
|
-
|
|
621
|
-
return publishedBlock?.block;
|
|
607
|
+
return await this.blockSource.getL2BlockByArchive(archive);
|
|
622
608
|
}
|
|
623
609
|
|
|
624
610
|
/**
|
|
@@ -628,19 +614,23 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
628
614
|
* @returns The blocks requested.
|
|
629
615
|
*/
|
|
630
616
|
public async getBlocks(from: BlockNumber, limit: number): Promise<L2Block[]> {
|
|
631
|
-
return (await this.blockSource.getBlocks(from, limit)) ?? [];
|
|
617
|
+
return (await this.blockSource.getBlocks(from, BlockNumber(limit))) ?? [];
|
|
632
618
|
}
|
|
633
619
|
|
|
634
|
-
public async
|
|
635
|
-
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)) ?? [];
|
|
636
626
|
}
|
|
637
627
|
|
|
638
628
|
/**
|
|
639
|
-
* Method to fetch the current
|
|
640
|
-
* @returns The current
|
|
629
|
+
* Method to fetch the current min L2 fees.
|
|
630
|
+
* @returns The current min L2 fees.
|
|
641
631
|
*/
|
|
642
|
-
public async
|
|
643
|
-
return await this.globalVariableBuilder.
|
|
632
|
+
public async getCurrentMinFees(): Promise<GasFees> {
|
|
633
|
+
return await this.globalVariableBuilder.getCurrentMinFees();
|
|
644
634
|
}
|
|
645
635
|
|
|
646
636
|
public async getMaxPriorityFees(): Promise<GasFees> {
|
|
@@ -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?: 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);
|
|
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> {
|
|
@@ -781,10 +813,19 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
781
813
|
await tryStop(this.p2pClient);
|
|
782
814
|
await tryStop(this.worldStateSynchronizer);
|
|
783
815
|
await tryStop(this.blockSource);
|
|
816
|
+
await tryStop(this.blobClient);
|
|
784
817
|
await tryStop(this.telemetry);
|
|
785
818
|
this.log.info(`Stopped Aztec Node`);
|
|
786
819
|
}
|
|
787
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
|
+
|
|
788
829
|
/**
|
|
789
830
|
* Method to retrieve pending txs.
|
|
790
831
|
* @param limit - The number of items to returns
|
|
@@ -817,20 +858,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
817
858
|
return compactArray(await Promise.all(txHashes.map(txHash => this.getTxByHash(txHash))));
|
|
818
859
|
}
|
|
819
860
|
|
|
820
|
-
/**
|
|
821
|
-
* Find the indexes of the given leaves in the given tree along with a block metadata pointing to the block in which
|
|
822
|
-
* the leaves were inserted.
|
|
823
|
-
* @param blockNumber - The block number at which to get the data or 'latest' for latest data.
|
|
824
|
-
* @param treeId - The tree to search in.
|
|
825
|
-
* @param leafValues - The values to search for.
|
|
826
|
-
* @returns The indices of leaves and the block metadata of a block in which the leaves were inserted.
|
|
827
|
-
*/
|
|
828
861
|
public async findLeavesIndexes(
|
|
829
|
-
|
|
862
|
+
block: BlockParameter,
|
|
830
863
|
treeId: MerkleTreeId,
|
|
831
864
|
leafValues: Fr[],
|
|
832
865
|
): Promise<(DataInBlock<bigint> | undefined)[]> {
|
|
833
|
-
const committedDb = await this.#getWorldState(
|
|
866
|
+
const committedDb = await this.#getWorldState(block);
|
|
834
867
|
const maybeIndices = await committedDb.findLeafIndices(
|
|
835
868
|
treeId,
|
|
836
869
|
leafValues.map(x => x.toBuffer()),
|
|
@@ -888,39 +921,27 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
888
921
|
});
|
|
889
922
|
}
|
|
890
923
|
|
|
891
|
-
/**
|
|
892
|
-
* Returns a sibling path for the given index in the nullifier tree.
|
|
893
|
-
* @param blockNumber - The block number at which to get the data.
|
|
894
|
-
* @param leafIndex - The index of the leaf for which the sibling path is required.
|
|
895
|
-
* @returns The sibling path for the leaf index.
|
|
896
|
-
*/
|
|
897
924
|
public async getNullifierSiblingPath(
|
|
898
|
-
|
|
925
|
+
block: BlockParameter,
|
|
899
926
|
leafIndex: bigint,
|
|
900
927
|
): Promise<SiblingPath<typeof NULLIFIER_TREE_HEIGHT>> {
|
|
901
|
-
const committedDb = await this.#getWorldState(
|
|
928
|
+
const committedDb = await this.#getWorldState(block);
|
|
902
929
|
return committedDb.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, leafIndex);
|
|
903
930
|
}
|
|
904
931
|
|
|
905
|
-
/**
|
|
906
|
-
* Returns a sibling path for the given index in the data tree.
|
|
907
|
-
* @param blockNumber - The block number at which to get the data.
|
|
908
|
-
* @param leafIndex - The index of the leaf for which the sibling path is required.
|
|
909
|
-
* @returns The sibling path for the leaf index.
|
|
910
|
-
*/
|
|
911
932
|
public async getNoteHashSiblingPath(
|
|
912
|
-
|
|
933
|
+
block: BlockParameter,
|
|
913
934
|
leafIndex: bigint,
|
|
914
935
|
): Promise<SiblingPath<typeof NOTE_HASH_TREE_HEIGHT>> {
|
|
915
|
-
const committedDb = await this.#getWorldState(
|
|
936
|
+
const committedDb = await this.#getWorldState(block);
|
|
916
937
|
return committedDb.getSiblingPath(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
|
|
917
938
|
}
|
|
918
939
|
|
|
919
940
|
public async getArchiveMembershipWitness(
|
|
920
|
-
|
|
941
|
+
block: BlockParameter,
|
|
921
942
|
archive: Fr,
|
|
922
943
|
): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined> {
|
|
923
|
-
const committedDb = await this.#getWorldState(
|
|
944
|
+
const committedDb = await this.#getWorldState(block);
|
|
924
945
|
const [pathAndIndex] = await committedDb.findSiblingPaths<MerkleTreeId.ARCHIVE>(MerkleTreeId.ARCHIVE, [archive]);
|
|
925
946
|
return pathAndIndex === undefined
|
|
926
947
|
? undefined
|
|
@@ -928,10 +949,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
928
949
|
}
|
|
929
950
|
|
|
930
951
|
public async getNoteHashMembershipWitness(
|
|
931
|
-
|
|
952
|
+
block: BlockParameter,
|
|
932
953
|
noteHash: Fr,
|
|
933
954
|
): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
|
|
934
|
-
const committedDb = await this.#getWorldState(
|
|
955
|
+
const committedDb = await this.#getWorldState(block);
|
|
935
956
|
const [pathAndIndex] = await committedDb.findSiblingPaths<MerkleTreeId.NOTE_HASH_TREE>(
|
|
936
957
|
MerkleTreeId.NOTE_HASH_TREE,
|
|
937
958
|
[noteHash],
|
|
@@ -941,17 +962,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
941
962
|
: MembershipWitness.fromSiblingPath(pathAndIndex.index, pathAndIndex.path);
|
|
942
963
|
}
|
|
943
964
|
|
|
944
|
-
/**
|
|
945
|
-
* Returns the index and a sibling path for a leaf in the committed l1 to l2 data tree.
|
|
946
|
-
* @param blockNumber - The block number at which to get the data.
|
|
947
|
-
* @param l1ToL2Message - The l1ToL2Message to get the index / sibling path for.
|
|
948
|
-
* @returns A tuple of the index and the sibling path of the L1ToL2Message (undefined if not found).
|
|
949
|
-
*/
|
|
950
965
|
public async getL1ToL2MessageMembershipWitness(
|
|
951
|
-
|
|
966
|
+
block: BlockParameter,
|
|
952
967
|
l1ToL2Message: Fr,
|
|
953
968
|
): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>] | undefined> {
|
|
954
|
-
const db = await this.#getWorldState(
|
|
969
|
+
const db = await this.#getWorldState(block);
|
|
955
970
|
const [witness] = await db.findSiblingPaths(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, [l1ToL2Message]);
|
|
956
971
|
if (!witness) {
|
|
957
972
|
return undefined;
|
|
@@ -979,56 +994,52 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
979
994
|
}
|
|
980
995
|
|
|
981
996
|
/**
|
|
982
|
-
* Returns all the L2 to L1 messages in
|
|
983
|
-
* @param
|
|
984
|
-
* @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).
|
|
985
1000
|
*/
|
|
986
|
-
public async getL2ToL1Messages(
|
|
987
|
-
|
|
988
|
-
|
|
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)),
|
|
989
1019
|
);
|
|
990
|
-
return block?.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs);
|
|
991
1020
|
}
|
|
992
1021
|
|
|
993
|
-
/**
|
|
994
|
-
* Returns a sibling path for a leaf in the committed blocks tree.
|
|
995
|
-
* @param blockNumber - The block number at which to get the data.
|
|
996
|
-
* @param leafIndex - Index of the leaf in the tree.
|
|
997
|
-
* @returns The sibling path.
|
|
998
|
-
*/
|
|
999
1022
|
public async getArchiveSiblingPath(
|
|
1000
|
-
|
|
1023
|
+
block: BlockParameter,
|
|
1001
1024
|
leafIndex: bigint,
|
|
1002
1025
|
): Promise<SiblingPath<typeof ARCHIVE_HEIGHT>> {
|
|
1003
|
-
const committedDb = await this.#getWorldState(
|
|
1026
|
+
const committedDb = await this.#getWorldState(block);
|
|
1004
1027
|
return committedDb.getSiblingPath(MerkleTreeId.ARCHIVE, leafIndex);
|
|
1005
1028
|
}
|
|
1006
1029
|
|
|
1007
|
-
/**
|
|
1008
|
-
* Returns a sibling path for a leaf in the committed public data tree.
|
|
1009
|
-
* @param blockNumber - The block number at which to get the data.
|
|
1010
|
-
* @param leafIndex - Index of the leaf in the tree.
|
|
1011
|
-
* @returns The sibling path.
|
|
1012
|
-
*/
|
|
1013
1030
|
public async getPublicDataSiblingPath(
|
|
1014
|
-
|
|
1031
|
+
block: BlockParameter,
|
|
1015
1032
|
leafIndex: bigint,
|
|
1016
1033
|
): Promise<SiblingPath<typeof PUBLIC_DATA_TREE_HEIGHT>> {
|
|
1017
|
-
const committedDb = await this.#getWorldState(
|
|
1034
|
+
const committedDb = await this.#getWorldState(block);
|
|
1018
1035
|
return committedDb.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, leafIndex);
|
|
1019
1036
|
}
|
|
1020
1037
|
|
|
1021
|
-
/**
|
|
1022
|
-
* Returns a nullifier membership witness for a given nullifier at a given block.
|
|
1023
|
-
* @param blockNumber - The block number at which to get the index.
|
|
1024
|
-
* @param nullifier - Nullifier we try to find witness for.
|
|
1025
|
-
* @returns The nullifier membership witness (if found).
|
|
1026
|
-
*/
|
|
1027
1038
|
public async getNullifierMembershipWitness(
|
|
1028
|
-
|
|
1039
|
+
block: BlockParameter,
|
|
1029
1040
|
nullifier: Fr,
|
|
1030
1041
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
1031
|
-
const db = await this.#getWorldState(
|
|
1042
|
+
const db = await this.#getWorldState(block);
|
|
1032
1043
|
const [witness] = await db.findSiblingPaths(MerkleTreeId.NULLIFIER_TREE, [nullifier.toBuffer()]);
|
|
1033
1044
|
if (!witness) {
|
|
1034
1045
|
return undefined;
|
|
@@ -1045,7 +1056,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1045
1056
|
|
|
1046
1057
|
/**
|
|
1047
1058
|
* Returns a low nullifier membership witness for a given nullifier at a given block.
|
|
1048
|
-
* @param
|
|
1059
|
+
* @param block - The block parameter (block number, block hash, or 'latest') at which to get the data.
|
|
1049
1060
|
* @param nullifier - Nullifier we try to find the low nullifier witness for.
|
|
1050
1061
|
* @returns The low nullifier membership witness (if found).
|
|
1051
1062
|
* @remarks Low nullifier witness can be used to perform a nullifier non-inclusion proof by leveraging the "linked
|
|
@@ -1058,10 +1069,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1058
1069
|
* TODO: This is a confusing behavior and we should eventually address that.
|
|
1059
1070
|
*/
|
|
1060
1071
|
public async getLowNullifierMembershipWitness(
|
|
1061
|
-
|
|
1072
|
+
block: BlockParameter,
|
|
1062
1073
|
nullifier: Fr,
|
|
1063
1074
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
1064
|
-
const committedDb = await this.#getWorldState(
|
|
1075
|
+
const committedDb = await this.#getWorldState(block);
|
|
1065
1076
|
const findResult = await committedDb.getPreviousValueIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBigInt());
|
|
1066
1077
|
if (!findResult) {
|
|
1067
1078
|
return undefined;
|
|
@@ -1076,8 +1087,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1076
1087
|
return new NullifierMembershipWitness(BigInt(index), preimageData as NullifierLeafPreimage, siblingPath);
|
|
1077
1088
|
}
|
|
1078
1089
|
|
|
1079
|
-
async getPublicDataWitness(
|
|
1080
|
-
const committedDb = await this.#getWorldState(
|
|
1090
|
+
async getPublicDataWitness(block: BlockParameter, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
|
|
1091
|
+
const committedDb = await this.#getWorldState(block);
|
|
1081
1092
|
const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
1082
1093
|
if (!lowLeafResult) {
|
|
1083
1094
|
return undefined;
|
|
@@ -1091,19 +1102,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1091
1102
|
}
|
|
1092
1103
|
}
|
|
1093
1104
|
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
*
|
|
1097
|
-
* @remarks The storage slot here refers to the slot as it is defined in Noir not the index in the merkle tree.
|
|
1098
|
-
* Aztec's version of `eth_getStorageAt`.
|
|
1099
|
-
*
|
|
1100
|
-
* @param contract - Address of the contract to query.
|
|
1101
|
-
* @param slot - Slot to query.
|
|
1102
|
-
* @param blockNumber - The block number at which to get the data or 'latest'.
|
|
1103
|
-
* @returns Storage value at the given contract slot.
|
|
1104
|
-
*/
|
|
1105
|
-
public async getPublicStorageAt(blockNumber: BlockParameter, contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
1106
|
-
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);
|
|
1107
1107
|
const leafSlot = await computePublicDataTreeLeafSlot(contract, slot);
|
|
1108
1108
|
|
|
1109
1109
|
const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
@@ -1117,24 +1117,23 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1117
1117
|
return preimage.leaf.value;
|
|
1118
1118
|
}
|
|
1119
1119
|
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
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
|
+
}
|
|
1138
1137
|
}
|
|
1139
1138
|
|
|
1140
1139
|
/**
|
|
@@ -1243,7 +1242,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1243
1242
|
l1ChainId: this.l1ChainId,
|
|
1244
1243
|
rollupVersion: this.version,
|
|
1245
1244
|
setupAllowList: this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions()),
|
|
1246
|
-
gasFees: await this.
|
|
1245
|
+
gasFees: await this.getCurrentMinFees(),
|
|
1247
1246
|
skipFeeEnforcement,
|
|
1248
1247
|
txsPermitted: !this.config.disableTransactions,
|
|
1249
1248
|
});
|
|
@@ -1315,7 +1314,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1315
1314
|
}
|
|
1316
1315
|
|
|
1317
1316
|
// And it has an L2 block hash
|
|
1318
|
-
const l2BlockHash = await archiver.getL2Tips().then(tips => tips.
|
|
1317
|
+
const l2BlockHash = await archiver.getL2Tips().then(tips => tips.proposed.hash);
|
|
1319
1318
|
if (!l2BlockHash) {
|
|
1320
1319
|
this.metrics.recordSnapshotError();
|
|
1321
1320
|
throw new Error(`Archiver has no latest L2 block hash downloaded. Cannot start snapshot.`);
|
|
@@ -1349,7 +1348,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1349
1348
|
throw new Error('Archiver implementation does not support rollbacks.');
|
|
1350
1349
|
}
|
|
1351
1350
|
|
|
1352
|
-
const finalizedBlock = await archiver.getL2Tips().then(tips => tips.finalized.number);
|
|
1351
|
+
const finalizedBlock = await archiver.getL2Tips().then(tips => tips.finalized.block.number);
|
|
1353
1352
|
if (targetBlock < finalizedBlock) {
|
|
1354
1353
|
if (force) {
|
|
1355
1354
|
this.log.warn(`Clearing world state database to allow rolling back behind finalized block ${finalizedBlock}`);
|
|
@@ -1410,16 +1409,19 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1410
1409
|
}
|
|
1411
1410
|
}
|
|
1412
1411
|
|
|
1412
|
+
#getInitialHeaderHash(): Promise<L2BlockHash> {
|
|
1413
|
+
if (!this.initialHeaderHashPromise) {
|
|
1414
|
+
this.initialHeaderHashPromise = this.worldStateSynchronizer.getCommitted().getInitialHeader().hash();
|
|
1415
|
+
}
|
|
1416
|
+
return this.initialHeaderHashPromise;
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1413
1419
|
/**
|
|
1414
1420
|
* Returns an instance of MerkleTreeOperations having first ensured the world state is fully synched
|
|
1415
|
-
* @param
|
|
1421
|
+
* @param block - The block parameter (block number, block hash, or 'latest') at which to get the data.
|
|
1416
1422
|
* @returns An instance of a committed MerkleTreeOperations
|
|
1417
1423
|
*/
|
|
1418
|
-
async #getWorldState(
|
|
1419
|
-
if (typeof blockNumber === 'number' && blockNumber < INITIAL_L2_BLOCK_NUM - 1) {
|
|
1420
|
-
throw new Error('Invalid block number to get world state for: ' + blockNumber);
|
|
1421
|
-
}
|
|
1422
|
-
|
|
1424
|
+
async #getWorldState(block: BlockParameter) {
|
|
1423
1425
|
let blockSyncedTo: BlockNumber = BlockNumber.ZERO;
|
|
1424
1426
|
try {
|
|
1425
1427
|
// Attempt to sync the world state if necessary
|
|
@@ -1428,15 +1430,40 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1428
1430
|
this.log.error(`Error getting world state: ${err}`);
|
|
1429
1431
|
}
|
|
1430
1432
|
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
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}`);
|
|
1434
1435
|
return this.worldStateSynchronizer.getCommitted();
|
|
1435
|
-
}
|
|
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();
|
|
1436
1453
|
this.log.debug(`Using snapshot for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
|
|
1437
|
-
return this.worldStateSynchronizer.getSnapshot(blockNumber
|
|
1438
|
-
}
|
|
1439
|
-
|
|
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);
|
|
1440
1467
|
}
|
|
1441
1468
|
}
|
|
1442
1469
|
|