@aztec/aztec-node 0.0.1-commit.9b94fc1 → 0.0.1-commit.c7c42ec
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/config.d.ts +5 -2
- package/dest/aztec-node/config.d.ts.map +1 -1
- package/dest/aztec-node/config.js +7 -1
- package/dest/aztec-node/server.d.ts +35 -46
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +85 -44
- package/dest/sentinel/sentinel.d.ts +3 -3
- package/dest/sentinel/sentinel.d.ts.map +1 -1
- package/dest/sentinel/sentinel.js +4 -4
- package/package.json +26 -26
- package/src/aztec-node/config.ts +12 -8
- package/src/aztec-node/server.ts +141 -89
- package/src/sentinel/sentinel.ts +5 -5
package/src/aztec-node/server.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { Archiver, createArchiver } from '@aztec/archiver';
|
|
2
2
|
import { BBCircuitVerifier, QueuedIVCVerifier, TestCircuitVerifier } from '@aztec/bb-prover';
|
|
3
|
-
import { type
|
|
3
|
+
import { type BlobClientInterface, createBlobClient } from '@aztec/blob-client/client';
|
|
4
|
+
import {
|
|
5
|
+
type BlobFileStoreMetadata,
|
|
6
|
+
createReadOnlyFileStoreBlobClients,
|
|
7
|
+
createWritableFileStoreBlobClient,
|
|
8
|
+
} from '@aztec/blob-client/filestore';
|
|
4
9
|
import {
|
|
5
10
|
ARCHIVE_HEIGHT,
|
|
6
11
|
INITIAL_L2_BLOCK_NUM,
|
|
@@ -10,17 +15,14 @@ import {
|
|
|
10
15
|
type PUBLIC_DATA_TREE_HEIGHT,
|
|
11
16
|
} from '@aztec/constants';
|
|
12
17
|
import { EpochCache, type EpochCacheInterface } from '@aztec/epoch-cache';
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
getPublicClient,
|
|
19
|
-
} from '@aztec/ethereum';
|
|
20
|
-
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
18
|
+
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
19
|
+
import { getPublicClient } from '@aztec/ethereum/client';
|
|
20
|
+
import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
21
|
+
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
22
|
+
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
21
23
|
import { compactArray, pick } from '@aztec/foundation/collection';
|
|
24
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
22
25
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
23
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
24
26
|
import { BadRequestError } from '@aztec/foundation/json-rpc';
|
|
25
27
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
26
28
|
import { count } from '@aztec/foundation/string';
|
|
@@ -28,7 +30,10 @@ import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
|
28
30
|
import { MembershipWitness, SiblingPath } from '@aztec/foundation/trees';
|
|
29
31
|
import { KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore';
|
|
30
32
|
import { trySnapshotSync, uploadSnapshot } from '@aztec/node-lib/actions';
|
|
31
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
createForwarderL1TxUtilsFromEthSigner,
|
|
35
|
+
createL1TxUtilsWithBlobsFromEthSigner,
|
|
36
|
+
} from '@aztec/node-lib/factories';
|
|
32
37
|
import { type P2P, type P2PClientDeps, createP2PClient, getDefaultAllowedSetupFunctions } from '@aztec/p2p';
|
|
33
38
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
34
39
|
import {
|
|
@@ -38,6 +43,7 @@ import {
|
|
|
38
43
|
type SequencerPublisher,
|
|
39
44
|
createValidatorForAcceptingTxs,
|
|
40
45
|
} from '@aztec/sequencer-client';
|
|
46
|
+
import { CheckpointsBuilder } from '@aztec/sequencer-client';
|
|
41
47
|
import { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
42
48
|
import {
|
|
43
49
|
AttestationsBlockWatcher,
|
|
@@ -46,13 +52,13 @@ import {
|
|
|
46
52
|
type Watcher,
|
|
47
53
|
createSlasher,
|
|
48
54
|
} from '@aztec/slasher';
|
|
49
|
-
import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
55
|
+
import { CollectionLimitsConfig, PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
50
56
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
51
57
|
import {
|
|
52
|
-
type
|
|
58
|
+
type BlockParameter,
|
|
59
|
+
type DataInBlock,
|
|
53
60
|
type L2Block,
|
|
54
61
|
L2BlockHash,
|
|
55
|
-
type L2BlockNumber,
|
|
56
62
|
type L2BlockSource,
|
|
57
63
|
type PublishedL2Block,
|
|
58
64
|
} from '@aztec/stdlib/block';
|
|
@@ -63,7 +69,7 @@ import type {
|
|
|
63
69
|
NodeInfo,
|
|
64
70
|
ProtocolContractAddresses,
|
|
65
71
|
} from '@aztec/stdlib/contract';
|
|
66
|
-
import
|
|
72
|
+
import { GasFees } from '@aztec/stdlib/gas';
|
|
67
73
|
import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
|
|
68
74
|
import {
|
|
69
75
|
type AztecNode,
|
|
@@ -82,7 +88,7 @@ import {
|
|
|
82
88
|
type WorldStateSynchronizer,
|
|
83
89
|
tryStop,
|
|
84
90
|
} from '@aztec/stdlib/interfaces/server';
|
|
85
|
-
import type { LogFilter,
|
|
91
|
+
import type { LogFilter, SiloedTag, Tag, TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
86
92
|
import { InboxLeaf, type L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
87
93
|
import { P2PClientType } from '@aztec/stdlib/p2p';
|
|
88
94
|
import type { Offense, SlashPayloadRound } from '@aztec/stdlib/slashing';
|
|
@@ -155,6 +161,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
155
161
|
private proofVerifier: ClientProtocolCircuitVerifier,
|
|
156
162
|
private telemetry: TelemetryClient = getTelemetryClient(),
|
|
157
163
|
private log = createLogger('node'),
|
|
164
|
+
private blobClient?: BlobClientInterface,
|
|
158
165
|
) {
|
|
159
166
|
this.metrics = new NodeMetrics(telemetry, 'AztecNodeService');
|
|
160
167
|
this.tracer = telemetry.getTracer('AztecNodeService');
|
|
@@ -184,7 +191,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
184
191
|
logger?: Logger;
|
|
185
192
|
publisher?: SequencerPublisher;
|
|
186
193
|
dateProvider?: DateProvider;
|
|
187
|
-
|
|
194
|
+
blobClient?: BlobClientInterface;
|
|
188
195
|
p2pClientDeps?: P2PClientDeps<P2PClientType.Full>;
|
|
189
196
|
} = {},
|
|
190
197
|
options: {
|
|
@@ -197,8 +204,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
197
204
|
const packageVersion = getPackageVersion() ?? '';
|
|
198
205
|
const telemetry = deps.telemetry ?? getTelemetryClient();
|
|
199
206
|
const dateProvider = deps.dateProvider ?? new DateProvider();
|
|
200
|
-
const blobSinkClient =
|
|
201
|
-
deps.blobSinkClient ?? createBlobSinkClient(config, { logger: createLogger('node:blob-sink:client') });
|
|
202
207
|
const ethereumChain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
|
|
203
208
|
|
|
204
209
|
// Build a key store from file if given or from environment otherwise
|
|
@@ -238,7 +243,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
238
243
|
|
|
239
244
|
const publicClient = createPublicClient({
|
|
240
245
|
chain: ethereumChain.chainInfo,
|
|
241
|
-
transport: fallback(config.l1RpcUrls.map((url: string) => http(url))),
|
|
246
|
+
transport: fallback(config.l1RpcUrls.map((url: string) => http(url, { batch: false }))),
|
|
242
247
|
pollingInterval: config.viemPollingIntervalMS,
|
|
243
248
|
});
|
|
244
249
|
|
|
@@ -266,6 +271,25 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
266
271
|
);
|
|
267
272
|
}
|
|
268
273
|
|
|
274
|
+
const blobFileStoreMetadata: BlobFileStoreMetadata = {
|
|
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
|
+
});
|
|
292
|
+
|
|
269
293
|
// attempt snapshot sync if possible
|
|
270
294
|
await trySnapshotSync(config, log);
|
|
271
295
|
|
|
@@ -273,7 +297,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
273
297
|
|
|
274
298
|
const archiver = await createArchiver(
|
|
275
299
|
config,
|
|
276
|
-
{
|
|
300
|
+
{ blobClient, epochCache, telemetry, dateProvider },
|
|
277
301
|
{ blockUntilSync: !config.skipArchiverInitialSync },
|
|
278
302
|
);
|
|
279
303
|
|
|
@@ -284,9 +308,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
284
308
|
options.prefilledPublicData,
|
|
285
309
|
telemetry,
|
|
286
310
|
);
|
|
287
|
-
const circuitVerifier =
|
|
288
|
-
|
|
289
|
-
|
|
311
|
+
const circuitVerifier =
|
|
312
|
+
config.realProofs || config.debugForceTxProofVerification
|
|
313
|
+
? await BBCircuitVerifier.new(config)
|
|
314
|
+
: new TestCircuitVerifier(config.proverTestVerificationDelayMs);
|
|
290
315
|
if (!config.realProofs) {
|
|
291
316
|
log.warn(`Aztec node is accepting fake proofs`);
|
|
292
317
|
}
|
|
@@ -330,6 +355,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
330
355
|
blockSource: archiver,
|
|
331
356
|
l1ToL2MessageSource: archiver,
|
|
332
357
|
keyStoreManager,
|
|
358
|
+
fileStoreBlobUploadClient: fileStoreUploadClient,
|
|
333
359
|
});
|
|
334
360
|
|
|
335
361
|
// If we have a validator client, register it as a source of offenses for the slasher,
|
|
@@ -403,7 +429,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
403
429
|
// Validator enabled, create/start relevant service
|
|
404
430
|
let sequencer: SequencerClient | undefined;
|
|
405
431
|
let slasherClient: SlasherClientInterface | undefined;
|
|
406
|
-
if (!config.disableValidator) {
|
|
432
|
+
if (!config.disableValidator && validatorClient) {
|
|
407
433
|
// We create a slasher only if we have a sequencer, since all slashing actions go through the sequencer publisher
|
|
408
434
|
// as they are executed when the node is selected as proposer.
|
|
409
435
|
const validatorAddresses = keyStoreManager
|
|
@@ -422,14 +448,29 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
422
448
|
);
|
|
423
449
|
await slasherClient.start();
|
|
424
450
|
|
|
425
|
-
const l1TxUtils =
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
451
|
+
const l1TxUtils = config.publisherForwarderAddress
|
|
452
|
+
? await createForwarderL1TxUtilsFromEthSigner(
|
|
453
|
+
publicClient,
|
|
454
|
+
keyStoreManager!.createAllValidatorPublisherSigners(),
|
|
455
|
+
config.publisherForwarderAddress,
|
|
456
|
+
{ ...config, scope: 'sequencer' },
|
|
457
|
+
{ telemetry, logger: log.createChild('l1-tx-utils'), dateProvider },
|
|
458
|
+
)
|
|
459
|
+
: await createL1TxUtilsWithBlobsFromEthSigner(
|
|
460
|
+
publicClient,
|
|
461
|
+
keyStoreManager!.createAllValidatorPublisherSigners(),
|
|
462
|
+
{ ...config, scope: 'sequencer' },
|
|
463
|
+
{ telemetry, logger: log.createChild('l1-tx-utils'), dateProvider },
|
|
464
|
+
);
|
|
431
465
|
|
|
432
466
|
// Create and start the sequencer client
|
|
467
|
+
const checkpointsBuilder = new CheckpointsBuilder(
|
|
468
|
+
{ ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
|
|
469
|
+
archiver,
|
|
470
|
+
dateProvider,
|
|
471
|
+
telemetry,
|
|
472
|
+
);
|
|
473
|
+
|
|
433
474
|
sequencer = await SequencerClient.new(config, {
|
|
434
475
|
...deps,
|
|
435
476
|
epochCache,
|
|
@@ -438,12 +479,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
438
479
|
p2pClient,
|
|
439
480
|
worldStateSynchronizer,
|
|
440
481
|
slasherClient,
|
|
441
|
-
|
|
482
|
+
checkpointsBuilder,
|
|
442
483
|
l2BlockSource: archiver,
|
|
443
484
|
l1ToL2MessageSource: archiver,
|
|
444
485
|
telemetry,
|
|
445
486
|
dateProvider,
|
|
446
|
-
|
|
487
|
+
blobClient,
|
|
447
488
|
nodeKeyStore: keyStoreManager!,
|
|
448
489
|
});
|
|
449
490
|
}
|
|
@@ -455,6 +496,13 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
455
496
|
log.warn(`Sequencer created but not started`);
|
|
456
497
|
}
|
|
457
498
|
|
|
499
|
+
const globalVariableBuilder = new GlobalVariableBuilder({
|
|
500
|
+
...config,
|
|
501
|
+
rollupVersion: BigInt(config.rollupVersion),
|
|
502
|
+
l1GenesisTime,
|
|
503
|
+
slotDuration: Number(slotDuration),
|
|
504
|
+
});
|
|
505
|
+
|
|
458
506
|
return new AztecNodeService(
|
|
459
507
|
config,
|
|
460
508
|
p2pClient,
|
|
@@ -469,12 +517,13 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
469
517
|
epochPruneWatcher,
|
|
470
518
|
ethereumChain.chainInfo.id,
|
|
471
519
|
config.rollupVersion,
|
|
472
|
-
|
|
520
|
+
globalVariableBuilder,
|
|
473
521
|
epochCache,
|
|
474
522
|
packageVersion,
|
|
475
523
|
proofVerifier,
|
|
476
524
|
telemetry,
|
|
477
525
|
log,
|
|
526
|
+
blobClient,
|
|
478
527
|
);
|
|
479
528
|
}
|
|
480
529
|
|
|
@@ -549,8 +598,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
549
598
|
* @param number - The block number being requested.
|
|
550
599
|
* @returns The requested block.
|
|
551
600
|
*/
|
|
552
|
-
public async getBlock(number:
|
|
553
|
-
const blockNumber = number === 'latest' ? await this.getBlockNumber() : number;
|
|
601
|
+
public async getBlock(number: BlockParameter): Promise<L2Block | undefined> {
|
|
602
|
+
const blockNumber = number === 'latest' ? await this.getBlockNumber() : (number as BlockNumber);
|
|
554
603
|
return await this.blockSource.getBlock(blockNumber);
|
|
555
604
|
}
|
|
556
605
|
|
|
@@ -580,11 +629,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
580
629
|
* @param limit - The maximum number of blocks to obtain.
|
|
581
630
|
* @returns The blocks requested.
|
|
582
631
|
*/
|
|
583
|
-
public async getBlocks(from:
|
|
632
|
+
public async getBlocks(from: BlockNumber, limit: number): Promise<L2Block[]> {
|
|
584
633
|
return (await this.blockSource.getBlocks(from, limit)) ?? [];
|
|
585
634
|
}
|
|
586
635
|
|
|
587
|
-
public async getPublishedBlocks(from:
|
|
636
|
+
public async getPublishedBlocks(from: BlockNumber, limit: number): Promise<PublishedL2Block[]> {
|
|
588
637
|
return (await this.blockSource.getPublishedBlocks(from, limit)) ?? [];
|
|
589
638
|
}
|
|
590
639
|
|
|
@@ -596,15 +645,23 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
596
645
|
return await this.globalVariableBuilder.getCurrentBaseFees();
|
|
597
646
|
}
|
|
598
647
|
|
|
648
|
+
public async getMaxPriorityFees(): Promise<GasFees> {
|
|
649
|
+
for await (const tx of this.p2pClient.iteratePendingTxs()) {
|
|
650
|
+
return tx.getGasSettings().maxPriorityFeesPerGas;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
return GasFees.from({ feePerDaGas: 0n, feePerL2Gas: 0n });
|
|
654
|
+
}
|
|
655
|
+
|
|
599
656
|
/**
|
|
600
657
|
* Method to fetch the latest block number synchronized by the node.
|
|
601
658
|
* @returns The block number.
|
|
602
659
|
*/
|
|
603
|
-
public async getBlockNumber(): Promise<
|
|
660
|
+
public async getBlockNumber(): Promise<BlockNumber> {
|
|
604
661
|
return await this.blockSource.getBlockNumber();
|
|
605
662
|
}
|
|
606
663
|
|
|
607
|
-
public async getProvenBlockNumber(): Promise<
|
|
664
|
+
public async getProvenBlockNumber(): Promise<BlockNumber> {
|
|
608
665
|
return await this.blockSource.getProvenBlockNumber();
|
|
609
666
|
}
|
|
610
667
|
|
|
@@ -640,25 +697,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
640
697
|
return this.contractDataSource.getContract(address);
|
|
641
698
|
}
|
|
642
699
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
* @param from - The block number from which to begin retrieving logs.
|
|
646
|
-
* @param limit - The maximum number of blocks to retrieve logs from.
|
|
647
|
-
* @returns An array of private logs from the specified range of blocks.
|
|
648
|
-
*/
|
|
649
|
-
public getPrivateLogs(from: number, limit: number): Promise<PrivateLog[]> {
|
|
650
|
-
return this.logsSource.getPrivateLogs(from, limit);
|
|
700
|
+
public getPrivateLogsByTags(tags: SiloedTag[]): Promise<TxScopedL2Log[][]> {
|
|
701
|
+
return this.logsSource.getPrivateLogsByTags(tags);
|
|
651
702
|
}
|
|
652
703
|
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
* @param tags - The tags to filter the logs by.
|
|
656
|
-
* @param logsPerTag - The maximum number of logs to return for each tag. By default no limit is set
|
|
657
|
-
* @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
|
|
658
|
-
* that tag.
|
|
659
|
-
*/
|
|
660
|
-
public getLogsByTags(tags: Fr[], logsPerTag?: number): Promise<TxScopedL2Log[][]> {
|
|
661
|
-
return this.logsSource.getLogsByTags(tags, logsPerTag);
|
|
704
|
+
public getPublicLogsByTagsFromContract(contractAddress: AztecAddress, tags: Tag[]): Promise<TxScopedL2Log[][]> {
|
|
705
|
+
return this.logsSource.getPublicLogsByTagsFromContract(contractAddress, tags);
|
|
662
706
|
}
|
|
663
707
|
|
|
664
708
|
/**
|
|
@@ -739,6 +783,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
739
783
|
await tryStop(this.p2pClient);
|
|
740
784
|
await tryStop(this.worldStateSynchronizer);
|
|
741
785
|
await tryStop(this.blockSource);
|
|
786
|
+
await tryStop(this.blobClient);
|
|
742
787
|
await tryStop(this.telemetry);
|
|
743
788
|
this.log.info(`Stopped Aztec Node`);
|
|
744
789
|
}
|
|
@@ -784,10 +829,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
784
829
|
* @returns The indices of leaves and the block metadata of a block in which the leaves were inserted.
|
|
785
830
|
*/
|
|
786
831
|
public async findLeavesIndexes(
|
|
787
|
-
blockNumber:
|
|
832
|
+
blockNumber: BlockParameter,
|
|
788
833
|
treeId: MerkleTreeId,
|
|
789
834
|
leafValues: Fr[],
|
|
790
|
-
): Promise<(
|
|
835
|
+
): Promise<(DataInBlock<bigint> | undefined)[]> {
|
|
791
836
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
792
837
|
const maybeIndices = await committedDb.findLeafIndices(
|
|
793
838
|
treeId,
|
|
@@ -813,7 +858,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
813
858
|
// (note that block number corresponds to the leaf index in the archive tree).
|
|
814
859
|
const blockHashes = await Promise.all(
|
|
815
860
|
uniqueBlockNumbers.map(blockNumber => {
|
|
816
|
-
return committedDb.getLeafValue(MerkleTreeId.ARCHIVE, blockNumber
|
|
861
|
+
return committedDb.getLeafValue(MerkleTreeId.ARCHIVE, BigInt(blockNumber));
|
|
817
862
|
}),
|
|
818
863
|
);
|
|
819
864
|
|
|
@@ -824,7 +869,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
824
869
|
}
|
|
825
870
|
}
|
|
826
871
|
|
|
827
|
-
// Create
|
|
872
|
+
// Create DataInBlock objects by combining indices, blockNumbers and blockHashes and return them.
|
|
828
873
|
return maybeIndices.map((index, i) => {
|
|
829
874
|
if (index === undefined) {
|
|
830
875
|
return undefined;
|
|
@@ -839,7 +884,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
839
884
|
return undefined;
|
|
840
885
|
}
|
|
841
886
|
return {
|
|
842
|
-
l2BlockNumber: Number(blockNumber),
|
|
887
|
+
l2BlockNumber: BlockNumber(Number(blockNumber)),
|
|
843
888
|
l2BlockHash: L2BlockHash.fromField(blockHash),
|
|
844
889
|
data: index,
|
|
845
890
|
};
|
|
@@ -853,7 +898,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
853
898
|
* @returns The sibling path for the leaf index.
|
|
854
899
|
*/
|
|
855
900
|
public async getNullifierSiblingPath(
|
|
856
|
-
blockNumber:
|
|
901
|
+
blockNumber: BlockParameter,
|
|
857
902
|
leafIndex: bigint,
|
|
858
903
|
): Promise<SiblingPath<typeof NULLIFIER_TREE_HEIGHT>> {
|
|
859
904
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
@@ -867,7 +912,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
867
912
|
* @returns The sibling path for the leaf index.
|
|
868
913
|
*/
|
|
869
914
|
public async getNoteHashSiblingPath(
|
|
870
|
-
blockNumber:
|
|
915
|
+
blockNumber: BlockParameter,
|
|
871
916
|
leafIndex: bigint,
|
|
872
917
|
): Promise<SiblingPath<typeof NOTE_HASH_TREE_HEIGHT>> {
|
|
873
918
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
@@ -875,7 +920,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
875
920
|
}
|
|
876
921
|
|
|
877
922
|
public async getArchiveMembershipWitness(
|
|
878
|
-
blockNumber:
|
|
923
|
+
blockNumber: BlockParameter,
|
|
879
924
|
archive: Fr,
|
|
880
925
|
): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined> {
|
|
881
926
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
@@ -886,7 +931,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
886
931
|
}
|
|
887
932
|
|
|
888
933
|
public async getNoteHashMembershipWitness(
|
|
889
|
-
blockNumber:
|
|
934
|
+
blockNumber: BlockParameter,
|
|
890
935
|
noteHash: Fr,
|
|
891
936
|
): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
|
|
892
937
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
@@ -906,7 +951,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
906
951
|
* @returns A tuple of the index and the sibling path of the L1ToL2Message (undefined if not found).
|
|
907
952
|
*/
|
|
908
953
|
public async getL1ToL2MessageMembershipWitness(
|
|
909
|
-
blockNumber:
|
|
954
|
+
blockNumber: BlockParameter,
|
|
910
955
|
l1ToL2Message: Fr,
|
|
911
956
|
): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>] | undefined> {
|
|
912
957
|
const db = await this.#getWorldState(blockNumber);
|
|
@@ -919,9 +964,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
919
964
|
return [witness.index, witness.path];
|
|
920
965
|
}
|
|
921
966
|
|
|
922
|
-
public async getL1ToL2MessageBlock(l1ToL2Message: Fr): Promise<
|
|
967
|
+
public async getL1ToL2MessageBlock(l1ToL2Message: Fr): Promise<BlockNumber | undefined> {
|
|
923
968
|
const messageIndex = await this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message);
|
|
924
|
-
return messageIndex
|
|
969
|
+
return messageIndex
|
|
970
|
+
? BlockNumber.fromCheckpointNumber(InboxLeaf.checkpointNumberFromIndex(messageIndex))
|
|
971
|
+
: undefined;
|
|
925
972
|
}
|
|
926
973
|
|
|
927
974
|
/**
|
|
@@ -939,8 +986,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
939
986
|
* @param blockNumber - The block number at which to get the data.
|
|
940
987
|
* @returns The L2 to L1 messages (undefined if the block number is not found).
|
|
941
988
|
*/
|
|
942
|
-
public async getL2ToL1Messages(blockNumber:
|
|
943
|
-
const block = await this.blockSource.getBlock(
|
|
989
|
+
public async getL2ToL1Messages(blockNumber: BlockParameter): Promise<Fr[][] | undefined> {
|
|
990
|
+
const block = await this.blockSource.getBlock(
|
|
991
|
+
blockNumber === 'latest' ? await this.getBlockNumber() : (blockNumber as BlockNumber),
|
|
992
|
+
);
|
|
944
993
|
return block?.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs);
|
|
945
994
|
}
|
|
946
995
|
|
|
@@ -951,7 +1000,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
951
1000
|
* @returns The sibling path.
|
|
952
1001
|
*/
|
|
953
1002
|
public async getArchiveSiblingPath(
|
|
954
|
-
blockNumber:
|
|
1003
|
+
blockNumber: BlockParameter,
|
|
955
1004
|
leafIndex: bigint,
|
|
956
1005
|
): Promise<SiblingPath<typeof ARCHIVE_HEIGHT>> {
|
|
957
1006
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
@@ -965,7 +1014,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
965
1014
|
* @returns The sibling path.
|
|
966
1015
|
*/
|
|
967
1016
|
public async getPublicDataSiblingPath(
|
|
968
|
-
blockNumber:
|
|
1017
|
+
blockNumber: BlockParameter,
|
|
969
1018
|
leafIndex: bigint,
|
|
970
1019
|
): Promise<SiblingPath<typeof PUBLIC_DATA_TREE_HEIGHT>> {
|
|
971
1020
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
@@ -979,7 +1028,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
979
1028
|
* @returns The nullifier membership witness (if found).
|
|
980
1029
|
*/
|
|
981
1030
|
public async getNullifierMembershipWitness(
|
|
982
|
-
blockNumber:
|
|
1031
|
+
blockNumber: BlockParameter,
|
|
983
1032
|
nullifier: Fr,
|
|
984
1033
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
985
1034
|
const db = await this.#getWorldState(blockNumber);
|
|
@@ -1012,7 +1061,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1012
1061
|
* TODO: This is a confusing behavior and we should eventually address that.
|
|
1013
1062
|
*/
|
|
1014
1063
|
public async getLowNullifierMembershipWitness(
|
|
1015
|
-
blockNumber:
|
|
1064
|
+
blockNumber: BlockParameter,
|
|
1016
1065
|
nullifier: Fr,
|
|
1017
1066
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
1018
1067
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
@@ -1030,7 +1079,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1030
1079
|
return new NullifierMembershipWitness(BigInt(index), preimageData as NullifierLeafPreimage, siblingPath);
|
|
1031
1080
|
}
|
|
1032
1081
|
|
|
1033
|
-
async getPublicDataWitness(blockNumber:
|
|
1082
|
+
async getPublicDataWitness(blockNumber: BlockParameter, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
|
|
1034
1083
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
1035
1084
|
const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
1036
1085
|
if (!lowLeafResult) {
|
|
@@ -1056,7 +1105,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1056
1105
|
* @param blockNumber - The block number at which to get the data or 'latest'.
|
|
1057
1106
|
* @returns Storage value at the given contract slot.
|
|
1058
1107
|
*/
|
|
1059
|
-
public async getPublicStorageAt(blockNumber:
|
|
1108
|
+
public async getPublicStorageAt(blockNumber: BlockParameter, contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
1060
1109
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
1061
1110
|
const leafSlot = await computePublicDataTreeLeafSlot(contract, slot);
|
|
1062
1111
|
|
|
@@ -1075,10 +1124,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1075
1124
|
* Returns the currently committed block header, or the initial header if no blocks have been produced.
|
|
1076
1125
|
* @returns The current committed block header.
|
|
1077
1126
|
*/
|
|
1078
|
-
public async getBlockHeader(blockNumber:
|
|
1079
|
-
return blockNumber ===
|
|
1127
|
+
public async getBlockHeader(blockNumber: BlockParameter = 'latest'): Promise<BlockHeader | undefined> {
|
|
1128
|
+
return blockNumber === BlockNumber.ZERO ||
|
|
1129
|
+
(blockNumber === 'latest' && (await this.blockSource.getBlockNumber()) === BlockNumber.ZERO)
|
|
1080
1130
|
? this.worldStateSynchronizer.getCommitted().getInitialHeader()
|
|
1081
|
-
: this.blockSource.getBlockHeader(blockNumber);
|
|
1131
|
+
: this.blockSource.getBlockHeader(blockNumber === 'latest' ? blockNumber : (blockNumber as BlockNumber));
|
|
1082
1132
|
}
|
|
1083
1133
|
|
|
1084
1134
|
/**
|
|
@@ -1122,7 +1172,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1122
1172
|
}
|
|
1123
1173
|
|
|
1124
1174
|
const txHash = tx.getTxHash();
|
|
1125
|
-
const blockNumber = (await this.blockSource.getBlockNumber()) + 1;
|
|
1175
|
+
const blockNumber = BlockNumber((await this.blockSource.getBlockNumber()) + 1);
|
|
1126
1176
|
|
|
1127
1177
|
// If sequencer is not initialized, we just set these values to zero for simulation.
|
|
1128
1178
|
const coinbase = EthAddress.ZERO;
|
|
@@ -1152,8 +1202,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1152
1202
|
collectDebugLogs: true,
|
|
1153
1203
|
collectHints: false,
|
|
1154
1204
|
collectCallMetadata: true,
|
|
1155
|
-
maxDebugLogMemoryReads: this.config.rpcSimulatePublicMaxDebugLogMemoryReads,
|
|
1156
1205
|
collectStatistics: false,
|
|
1206
|
+
collectionLimits: CollectionLimitsConfig.from({
|
|
1207
|
+
maxDebugLogMemoryReads: this.config.rpcSimulatePublicMaxDebugLogMemoryReads,
|
|
1208
|
+
}),
|
|
1157
1209
|
});
|
|
1158
1210
|
const processor = publicProcessorFactory.create(merkleTreeFork, newGlobalVariables, config);
|
|
1159
1211
|
|
|
@@ -1187,7 +1239,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1187
1239
|
|
|
1188
1240
|
// We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
|
|
1189
1241
|
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
1190
|
-
const blockNumber = (await this.blockSource.getBlockNumber()) + 1;
|
|
1242
|
+
const blockNumber = BlockNumber((await this.blockSource.getBlockNumber()) + 1);
|
|
1191
1243
|
const validator = createValidatorForAcceptingTxs(db, this.contractDataSource, verifier, {
|
|
1192
1244
|
timestamp: nextSlotTimestamp,
|
|
1193
1245
|
blockNumber,
|
|
@@ -1294,7 +1346,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1294
1346
|
return Promise.resolve();
|
|
1295
1347
|
}
|
|
1296
1348
|
|
|
1297
|
-
public async rollbackTo(targetBlock:
|
|
1349
|
+
public async rollbackTo(targetBlock: BlockNumber, force?: boolean): Promise<void> {
|
|
1298
1350
|
const archiver = this.blockSource as Archiver;
|
|
1299
1351
|
if (!('rollbackTo' in archiver)) {
|
|
1300
1352
|
throw new Error('Archiver implementation does not support rollbacks.');
|
|
@@ -1366,12 +1418,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1366
1418
|
* @param blockNumber - The block number at which to get the data.
|
|
1367
1419
|
* @returns An instance of a committed MerkleTreeOperations
|
|
1368
1420
|
*/
|
|
1369
|
-
async #getWorldState(blockNumber:
|
|
1421
|
+
async #getWorldState(blockNumber: BlockParameter) {
|
|
1370
1422
|
if (typeof blockNumber === 'number' && blockNumber < INITIAL_L2_BLOCK_NUM - 1) {
|
|
1371
1423
|
throw new Error('Invalid block number to get world state for: ' + blockNumber);
|
|
1372
1424
|
}
|
|
1373
1425
|
|
|
1374
|
-
let blockSyncedTo:
|
|
1426
|
+
let blockSyncedTo: BlockNumber = BlockNumber.ZERO;
|
|
1375
1427
|
try {
|
|
1376
1428
|
// Attempt to sync the world state if necessary
|
|
1377
1429
|
blockSyncedTo = await this.#syncWorldState();
|
|
@@ -1385,7 +1437,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1385
1437
|
return this.worldStateSynchronizer.getCommitted();
|
|
1386
1438
|
} else if (blockNumber <= blockSyncedTo) {
|
|
1387
1439
|
this.log.debug(`Using snapshot for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
|
|
1388
|
-
return this.worldStateSynchronizer.getSnapshot(blockNumber);
|
|
1440
|
+
return this.worldStateSynchronizer.getSnapshot(blockNumber as BlockNumber);
|
|
1389
1441
|
} else {
|
|
1390
1442
|
throw new Error(`Block ${blockNumber} not yet synced`);
|
|
1391
1443
|
}
|
|
@@ -1395,8 +1447,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1395
1447
|
* Ensure we fully sync the world state
|
|
1396
1448
|
* @returns A promise that fulfils once the world state is synced
|
|
1397
1449
|
*/
|
|
1398
|
-
async #syncWorldState(): Promise<
|
|
1450
|
+
async #syncWorldState(): Promise<BlockNumber> {
|
|
1399
1451
|
const blockSourceHeight = await this.blockSource.getBlockNumber();
|
|
1400
|
-
return this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
|
|
1452
|
+
return await this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
|
|
1401
1453
|
}
|
|
1402
1454
|
}
|
package/src/sentinel/sentinel.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EpochCache } from '@aztec/epoch-cache';
|
|
2
|
-
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { BlockNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import { countWhile, filterAsync, fromEntries, getEntries, mapValues } from '@aztec/foundation/collection';
|
|
4
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
@@ -44,7 +44,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
44
44
|
protected initialSlot: SlotNumber | undefined;
|
|
45
45
|
protected lastProcessedSlot: SlotNumber | undefined;
|
|
46
46
|
// eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
|
|
47
|
-
protected slotNumberToBlock: Map<SlotNumber, { blockNumber:
|
|
47
|
+
protected slotNumberToBlock: Map<SlotNumber, { blockNumber: BlockNumber; archive: string; attestors: EthAddress[] }> =
|
|
48
48
|
new Map();
|
|
49
49
|
|
|
50
50
|
constructor(
|
|
@@ -76,7 +76,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
76
76
|
/** Loads initial slot and initializes blockstream. We will not process anything at or before the initial slot. */
|
|
77
77
|
protected async init() {
|
|
78
78
|
this.initialSlot = this.epochCache.getEpochAndSlotNow().slot;
|
|
79
|
-
const startingBlock = await this.archiver.getBlockNumber();
|
|
79
|
+
const startingBlock = BlockNumber(await this.archiver.getBlockNumber());
|
|
80
80
|
this.logger.info(`Starting validator sentinel with initial slot ${this.initialSlot} and block ${startingBlock}`);
|
|
81
81
|
this.blockStream = new L2BlockStream(this.archiver, this.l2TipsStore, this, this.logger, { startingBlock });
|
|
82
82
|
}
|
|
@@ -91,7 +91,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
91
91
|
// Store mapping from slot to archive, block number, and attestors
|
|
92
92
|
for (const block of event.blocks) {
|
|
93
93
|
this.slotNumberToBlock.set(block.block.header.getSlot(), {
|
|
94
|
-
blockNumber: block.block.number,
|
|
94
|
+
blockNumber: BlockNumber(block.block.number),
|
|
95
95
|
archive: block.block.archive.root.toString(),
|
|
96
96
|
attestors: getAttestationInfoFromPublishedL2Block(block)
|
|
97
97
|
.filter(a => a.status === 'recovered-from-signature')
|
|
@@ -118,7 +118,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
118
118
|
if (event.type !== 'chain-proven') {
|
|
119
119
|
return;
|
|
120
120
|
}
|
|
121
|
-
const blockNumber = event.block.number;
|
|
121
|
+
const blockNumber = BlockNumber(event.block.number);
|
|
122
122
|
const block = await this.archiver.getBlock(blockNumber);
|
|
123
123
|
if (!block) {
|
|
124
124
|
this.logger.error(`Failed to get block ${blockNumber}`, { block });
|