@aztec/sequencer-client 0.0.1-commit.6c91f13 → 0.0.1-commit.96bb3f7
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/client/sequencer-client.d.ts +4 -5
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +8 -1
- package/dest/global_variable_builder/global_builder.d.ts +4 -4
- package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
- package/dest/global_variable_builder/global_builder.js +12 -12
- package/dest/index.d.ts +2 -3
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -2
- package/dest/publisher/sequencer-publisher-metrics.d.ts +1 -1
- package/dest/publisher/sequencer-publisher-metrics.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-metrics.js +15 -86
- package/dest/publisher/sequencer-publisher.d.ts +17 -16
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +442 -49
- package/dest/sequencer/block_builder.d.ts +1 -1
- package/dest/sequencer/block_builder.d.ts.map +1 -1
- package/dest/sequencer/block_builder.js +1 -1
- package/dest/sequencer/checkpoint_proposal_job.d.ts +11 -8
- package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_proposal_job.js +475 -28
- package/dest/sequencer/index.d.ts +1 -2
- package/dest/sequencer/index.d.ts.map +1 -1
- package/dest/sequencer/index.js +0 -1
- package/dest/sequencer/metrics.d.ts +3 -3
- package/dest/sequencer/metrics.d.ts.map +1 -1
- package/dest/sequencer/metrics.js +30 -121
- package/dest/sequencer/sequencer.d.ts +13 -11
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +425 -37
- package/dest/test/index.d.ts +2 -3
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/mock_checkpoint_builder.d.ts +10 -2
- package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
- package/dest/test/mock_checkpoint_builder.js +23 -0
- package/dest/test/utils.d.ts +8 -4
- package/dest/test/utils.d.ts.map +1 -1
- package/dest/test/utils.js +21 -12
- package/package.json +27 -27
- package/src/client/sequencer-client.ts +3 -4
- package/src/config.ts +7 -0
- package/src/global_variable_builder/global_builder.ts +12 -12
- package/src/index.ts +0 -3
- package/src/publisher/sequencer-publisher-metrics.ts +14 -70
- package/src/publisher/sequencer-publisher.ts +84 -73
- package/src/sequencer/block_builder.ts +1 -2
- package/src/sequencer/checkpoint_proposal_job.ts +75 -39
- package/src/sequencer/index.ts +0 -1
- package/src/sequencer/metrics.ts +23 -131
- package/src/sequencer/sequencer.ts +46 -35
- package/src/test/index.ts +1 -2
- package/src/test/mock_checkpoint_builder.ts +34 -2
- package/src/test/utils.ts +39 -19
- package/dest/sequencer/checkpoint_builder.d.ts +0 -63
- package/dest/sequencer/checkpoint_builder.d.ts.map +0 -1
- package/dest/sequencer/checkpoint_builder.js +0 -131
- package/dest/tx_validator/nullifier_cache.d.ts +0 -14
- package/dest/tx_validator/nullifier_cache.d.ts.map +0 -1
- package/dest/tx_validator/nullifier_cache.js +0 -24
- package/dest/tx_validator/tx_validator_factory.d.ts +0 -18
- package/dest/tx_validator/tx_validator_factory.d.ts.map +0 -1
- package/dest/tx_validator/tx_validator_factory.js +0 -53
- package/src/sequencer/checkpoint_builder.ts +0 -217
- package/src/tx_validator/nullifier_cache.ts +0 -30
- package/src/tx_validator/tx_validator_factory.ts +0 -133
|
@@ -12,7 +12,7 @@ import type { DateProvider } from '@aztec/foundation/timer';
|
|
|
12
12
|
import type { TypedEventEmitter } from '@aztec/foundation/types';
|
|
13
13
|
import type { P2P } from '@aztec/p2p';
|
|
14
14
|
import type { SlasherClientInterface } from '@aztec/slasher';
|
|
15
|
-
import type { L2BlockNew, L2BlockSource,
|
|
15
|
+
import type { L2BlockNew, L2BlockSink, L2BlockSource, ValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
16
16
|
import type { Checkpoint } from '@aztec/stdlib/checkpoint';
|
|
17
17
|
import { getSlotAtTimestamp, getSlotStartBuildTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
18
18
|
import {
|
|
@@ -24,16 +24,15 @@ import {
|
|
|
24
24
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
25
25
|
import { pickFromSchema } from '@aztec/stdlib/schemas';
|
|
26
26
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
27
|
-
import { type TelemetryClient, type Tracer, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
28
|
-
import type
|
|
27
|
+
import { Attributes, type TelemetryClient, type Tracer, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
28
|
+
import { FullNodeCheckpointsBuilder, type ValidatorClient } from '@aztec/validator-client';
|
|
29
29
|
|
|
30
30
|
import EventEmitter from 'node:events';
|
|
31
31
|
|
|
32
32
|
import { DefaultSequencerConfig } from '../config.js';
|
|
33
33
|
import type { GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
|
|
34
34
|
import type { SequencerPublisherFactory } from '../publisher/sequencer-publisher-factory.js';
|
|
35
|
-
import type {
|
|
36
|
-
import { FullNodeCheckpointsBuilder } from './checkpoint_builder.js';
|
|
35
|
+
import type { InvalidateCheckpointRequest, SequencerPublisher } from '../publisher/sequencer-publisher.js';
|
|
37
36
|
import { CheckpointProposalJob } from './checkpoint_proposal_job.js';
|
|
38
37
|
import { CheckpointVoter } from './checkpoint_voter.js';
|
|
39
38
|
import { SequencerInterruptedError, SequencerTooSlowError } from './errors.js';
|
|
@@ -91,7 +90,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
91
90
|
protected p2pClient: P2P,
|
|
92
91
|
protected worldState: WorldStateSynchronizer,
|
|
93
92
|
protected slasherClient: SlasherClientInterface | undefined,
|
|
94
|
-
protected l2BlockSource: L2BlockSource,
|
|
93
|
+
protected l2BlockSource: L2BlockSource & L2BlockSink,
|
|
95
94
|
protected l1ToL2MessageSource: L1ToL2MessageSource,
|
|
96
95
|
protected checkpointsBuilder: FullNodeCheckpointsBuilder,
|
|
97
96
|
protected l1Constants: SequencerRollupConstants,
|
|
@@ -160,7 +159,6 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
160
159
|
this.log.info('Stopped sequencer');
|
|
161
160
|
}
|
|
162
161
|
|
|
163
|
-
@trackSpan('Sequencer.work')
|
|
164
162
|
/** Main sequencer loop with a try/catch */
|
|
165
163
|
protected async safeWork() {
|
|
166
164
|
try {
|
|
@@ -198,6 +196,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
198
196
|
* - Collect attestations for the final block
|
|
199
197
|
* - Submit checkpoint
|
|
200
198
|
*/
|
|
199
|
+
@trackSpan('Sequencer.work')
|
|
201
200
|
protected async work() {
|
|
202
201
|
this.setState(SequencerState.SYNCHRONIZING, undefined);
|
|
203
202
|
const { slot, ts, now, epoch } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
@@ -233,6 +232,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
233
232
|
* This is the initial step in the main loop.
|
|
234
233
|
* @returns CheckpointProposalJob if successful, undefined if we are not yet synced or are not the proposer.
|
|
235
234
|
*/
|
|
235
|
+
@trackSpan('Sequencer.prepareCheckpointProposal')
|
|
236
236
|
private async prepareCheckpointProposal(
|
|
237
237
|
slot: SlotNumber,
|
|
238
238
|
ts: bigint,
|
|
@@ -263,8 +263,8 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
263
263
|
return undefined;
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
-
//
|
|
267
|
-
const checkpointNumber = CheckpointNumber
|
|
266
|
+
// Next checkpoint follows from the last synced one
|
|
267
|
+
const checkpointNumber = CheckpointNumber(syncedTo.checkpointNumber + 1);
|
|
268
268
|
|
|
269
269
|
const logCtx = {
|
|
270
270
|
now,
|
|
@@ -280,9 +280,9 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
280
280
|
this.setState(SequencerState.PROPOSER_CHECK, slot);
|
|
281
281
|
const [canPropose, proposer] = await this.checkCanPropose(slot);
|
|
282
282
|
|
|
283
|
-
// If we are not a proposer check if we should invalidate
|
|
283
|
+
// If we are not a proposer check if we should invalidate an invalid checkpoint, and bail
|
|
284
284
|
if (!canPropose) {
|
|
285
|
-
await this.
|
|
285
|
+
await this.considerInvalidatingCheckpoint(syncedTo, slot);
|
|
286
286
|
return undefined;
|
|
287
287
|
}
|
|
288
288
|
|
|
@@ -312,15 +312,14 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
312
312
|
}
|
|
313
313
|
|
|
314
314
|
// Prepare invalidation request if the pending chain is invalid (returns undefined if no need)
|
|
315
|
-
|
|
316
|
-
const invalidateBlock = await publisher.simulateInvalidateBlock(syncedTo.pendingChainValidationStatus);
|
|
315
|
+
const invalidateCheckpoint = await publisher.simulateInvalidateCheckpoint(syncedTo.pendingChainValidationStatus);
|
|
317
316
|
|
|
318
317
|
// Check with the rollup contract if we can indeed propose at the next L2 slot. This check should not fail
|
|
319
318
|
// if all the previous checks are good, but we do it just in case.
|
|
320
319
|
const canProposeCheck = await publisher.canProposeAtNextEthBlock(
|
|
321
320
|
syncedTo.archive,
|
|
322
321
|
proposer ?? EthAddress.ZERO,
|
|
323
|
-
|
|
322
|
+
invalidateCheckpoint,
|
|
324
323
|
);
|
|
325
324
|
|
|
326
325
|
if (canProposeCheck === undefined) {
|
|
@@ -364,7 +363,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
364
363
|
proposer,
|
|
365
364
|
publisher,
|
|
366
365
|
attestorAddress,
|
|
367
|
-
|
|
366
|
+
invalidateCheckpoint,
|
|
368
367
|
);
|
|
369
368
|
}
|
|
370
369
|
|
|
@@ -375,7 +374,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
375
374
|
proposer: EthAddress | undefined,
|
|
376
375
|
publisher: SequencerPublisher,
|
|
377
376
|
attestorAddress: EthAddress,
|
|
378
|
-
|
|
377
|
+
invalidateCheckpoint: InvalidateCheckpointRequest | undefined,
|
|
379
378
|
): CheckpointProposalJob {
|
|
380
379
|
return new CheckpointProposalJob(
|
|
381
380
|
slot,
|
|
@@ -384,13 +383,14 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
384
383
|
proposer,
|
|
385
384
|
publisher,
|
|
386
385
|
attestorAddress,
|
|
387
|
-
|
|
386
|
+
invalidateCheckpoint,
|
|
388
387
|
this.validatorClient,
|
|
389
388
|
this.globalsBuilder,
|
|
390
389
|
this.p2pClient,
|
|
391
390
|
this.worldState,
|
|
392
391
|
this.l1ToL2MessageSource,
|
|
393
392
|
this.checkpointsBuilder,
|
|
393
|
+
this.l2BlockSource,
|
|
394
394
|
this.l1Constants,
|
|
395
395
|
this.config,
|
|
396
396
|
this.timetable,
|
|
@@ -401,6 +401,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
401
401
|
this,
|
|
402
402
|
this.setState.bind(this),
|
|
403
403
|
this.log,
|
|
404
|
+
this.tracer,
|
|
404
405
|
);
|
|
405
406
|
}
|
|
406
407
|
|
|
@@ -469,9 +470,9 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
469
470
|
number: syncSummary.latestBlockNumber,
|
|
470
471
|
hash: syncSummary.latestBlockHash,
|
|
471
472
|
})),
|
|
472
|
-
this.l2BlockSource.getL2Tips().then(t => t.
|
|
473
|
+
this.l2BlockSource.getL2Tips().then(t => t.proposed),
|
|
473
474
|
this.p2pClient.getStatus().then(p2p => p2p.syncedToL2Block),
|
|
474
|
-
this.l1ToL2MessageSource.getL2Tips().then(t => t.
|
|
475
|
+
this.l1ToL2MessageSource.getL2Tips().then(t => t.proposed),
|
|
475
476
|
this.l2BlockSource.getPendingChainValidationStatus(),
|
|
476
477
|
] as const);
|
|
477
478
|
|
|
@@ -479,6 +480,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
479
480
|
|
|
480
481
|
// Handle zero as a special case, since the block hash won't match across services if we're changing the prefilled data for the genesis block,
|
|
481
482
|
// as the world state can compute the new genesis block hash, but other components use the hardcoded constant.
|
|
483
|
+
// TODO(palla/mbps): Fix the above. All components should be able to handle dynamic genesis block hashes.
|
|
482
484
|
const result =
|
|
483
485
|
(l2BlockSource.number === 0 && worldState.number === 0 && p2p.number === 0 && l1ToL2MessageSource.number === 0) ||
|
|
484
486
|
(worldState.hash === l2BlockSource.hash &&
|
|
@@ -494,7 +496,13 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
494
496
|
const blockNumber = worldState.number;
|
|
495
497
|
if (blockNumber < INITIAL_L2_BLOCK_NUM) {
|
|
496
498
|
const archive = new Fr((await this.worldState.getCommitted().getTreeInfo(MerkleTreeId.ARCHIVE)).root);
|
|
497
|
-
return {
|
|
499
|
+
return {
|
|
500
|
+
checkpointNumber: CheckpointNumber.ZERO,
|
|
501
|
+
blockNumber: BlockNumber.ZERO,
|
|
502
|
+
archive,
|
|
503
|
+
l1Timestamp,
|
|
504
|
+
pendingChainValidationStatus,
|
|
505
|
+
};
|
|
498
506
|
}
|
|
499
507
|
|
|
500
508
|
const block = await this.l2BlockSource.getL2BlockNew(blockNumber);
|
|
@@ -507,6 +515,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
507
515
|
return {
|
|
508
516
|
block,
|
|
509
517
|
blockNumber: block.number,
|
|
518
|
+
checkpointNumber: block.checkpointNumber,
|
|
510
519
|
archive: block.archive.root,
|
|
511
520
|
l1Timestamp,
|
|
512
521
|
pendingChainValidationStatus,
|
|
@@ -555,6 +564,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
555
564
|
* Tries to vote on slashing actions and governance when the sync check fails but we're past the max time for initializing a proposal.
|
|
556
565
|
* This allows the sequencer to participate in governance/slashing votes even when it cannot build blocks.
|
|
557
566
|
*/
|
|
567
|
+
@trackSpan('Seqeuencer.tryVoteWhenSyncFails', ({ slot }) => ({ [Attributes.SLOT_NUMBER]: slot }))
|
|
558
568
|
protected async tryVoteWhenSyncFails(args: { slot: SlotNumber; ts: bigint }): Promise<void> {
|
|
559
569
|
const { slot } = args;
|
|
560
570
|
|
|
@@ -626,12 +636,12 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
626
636
|
}
|
|
627
637
|
|
|
628
638
|
/**
|
|
629
|
-
* Considers invalidating a
|
|
639
|
+
* Considers invalidating a checkpoint if the pending chain is invalid. Depends on how long the invalid checkpoint
|
|
630
640
|
* has been there without being invalidated and whether the sequencer is in the committee or not. We always
|
|
631
641
|
* have the proposer try to invalidate, but if they fail, the sequencers in the committee are expected to try,
|
|
632
642
|
* and if they fail, any sequencer will try as well.
|
|
633
643
|
*/
|
|
634
|
-
protected async
|
|
644
|
+
protected async considerInvalidatingCheckpoint(
|
|
635
645
|
syncedTo: SequencerSyncCheckResult,
|
|
636
646
|
currentSlot: SlotNumber,
|
|
637
647
|
): Promise<void> {
|
|
@@ -640,18 +650,18 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
640
650
|
return;
|
|
641
651
|
}
|
|
642
652
|
|
|
643
|
-
const
|
|
644
|
-
const
|
|
645
|
-
const timeSinceChainInvalid = this.dateProvider.nowInSeconds() - Number(
|
|
653
|
+
const invalidCheckpointNumber = pendingChainValidationStatus.checkpoint.checkpointNumber;
|
|
654
|
+
const invalidCheckpointTimestamp = pendingChainValidationStatus.checkpoint.timestamp;
|
|
655
|
+
const timeSinceChainInvalid = this.dateProvider.nowInSeconds() - Number(invalidCheckpointTimestamp);
|
|
646
656
|
const ourValidatorAddresses = this.validatorClient.getValidatorAddresses();
|
|
647
657
|
|
|
648
658
|
const { secondsBeforeInvalidatingBlockAsCommitteeMember, secondsBeforeInvalidatingBlockAsNonCommitteeMember } =
|
|
649
659
|
this.config;
|
|
650
660
|
|
|
651
661
|
const logData = {
|
|
652
|
-
invalidL1Timestamp:
|
|
662
|
+
invalidL1Timestamp: invalidCheckpointTimestamp,
|
|
653
663
|
l1Timestamp,
|
|
654
|
-
|
|
664
|
+
invalidCheckpoint: pendingChainValidationStatus.checkpoint,
|
|
655
665
|
secondsBeforeInvalidatingBlockAsCommitteeMember,
|
|
656
666
|
secondsBeforeInvalidatingBlockAsNonCommitteeMember,
|
|
657
667
|
ourValidatorAddresses,
|
|
@@ -697,25 +707,25 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
697
707
|
|
|
698
708
|
const { publisher } = await this.publisherFactory.create(validatorToUse);
|
|
699
709
|
|
|
700
|
-
const
|
|
701
|
-
if (!
|
|
702
|
-
this.log.warn(`Failed to simulate invalidate
|
|
710
|
+
const invalidateCheckpoint = await publisher.simulateInvalidateCheckpoint(pendingChainValidationStatus);
|
|
711
|
+
if (!invalidateCheckpoint) {
|
|
712
|
+
this.log.warn(`Failed to simulate invalidate checkpoint`, logData);
|
|
703
713
|
return;
|
|
704
714
|
}
|
|
705
715
|
|
|
706
716
|
this.log.info(
|
|
707
717
|
invalidateAsCommitteeMember
|
|
708
|
-
? `Invalidating
|
|
709
|
-
: `Invalidating
|
|
718
|
+
? `Invalidating checkpoint ${invalidCheckpointNumber} as committee member`
|
|
719
|
+
: `Invalidating checkpoint ${invalidCheckpointNumber} as non-committee member`,
|
|
710
720
|
logData,
|
|
711
721
|
);
|
|
712
722
|
|
|
713
|
-
publisher.
|
|
723
|
+
publisher.enqueueInvalidateCheckpoint(invalidateCheckpoint);
|
|
714
724
|
|
|
715
725
|
if (!this.config.fishermanMode) {
|
|
716
726
|
await publisher.sendRequests();
|
|
717
727
|
} else {
|
|
718
|
-
this.log.info('Invalidating
|
|
728
|
+
this.log.info('Invalidating checkpoint in fisherman mode, clearing pending requests');
|
|
719
729
|
publisher.clearPendingRequests();
|
|
720
730
|
}
|
|
721
731
|
}
|
|
@@ -789,8 +799,9 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
789
799
|
|
|
790
800
|
type SequencerSyncCheckResult = {
|
|
791
801
|
block?: L2BlockNew;
|
|
802
|
+
checkpointNumber: CheckpointNumber;
|
|
792
803
|
blockNumber: BlockNumber;
|
|
793
804
|
archive: Fr;
|
|
794
805
|
l1Timestamp: bigint;
|
|
795
|
-
pendingChainValidationStatus:
|
|
806
|
+
pendingChainValidationStatus: ValidateCheckpointResult;
|
|
796
807
|
};
|
package/src/test/index.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { L1TxUtilsWithBlobs } from '@aztec/ethereum/l1-tx-utils-with-blobs';
|
|
2
2
|
import type { PublisherManager } from '@aztec/ethereum/publisher-manager';
|
|
3
3
|
import type { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
4
|
-
import type { ValidatorClient } from '@aztec/validator-client';
|
|
4
|
+
import type { FullNodeCheckpointsBuilder, ValidatorClient } from '@aztec/validator-client';
|
|
5
5
|
|
|
6
6
|
import { SequencerClient } from '../client/sequencer-client.js';
|
|
7
7
|
import type { SequencerPublisherFactory } from '../publisher/sequencer-publisher-factory.js';
|
|
8
8
|
import type { SequencerPublisher } from '../publisher/sequencer-publisher.js';
|
|
9
|
-
import type { FullNodeCheckpointsBuilder } from '../sequencer/checkpoint_builder.js';
|
|
10
9
|
import { Sequencer } from '../sequencer/sequencer.js';
|
|
11
10
|
import type { SequencerTimetable } from '../sequencer/timetable.js';
|
|
12
11
|
|
|
@@ -9,12 +9,11 @@ import type { FullNodeBlockBuilderConfig, PublicProcessorLimits } from '@aztec/s
|
|
|
9
9
|
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
10
10
|
import { makeAppendOnlyTreeSnapshot } from '@aztec/stdlib/testing';
|
|
11
11
|
import type { CheckpointGlobalVariables, Tx } from '@aztec/stdlib/tx';
|
|
12
|
-
|
|
13
12
|
import type {
|
|
14
13
|
BuildBlockInCheckpointResult,
|
|
15
14
|
CheckpointBuilder,
|
|
16
15
|
FullNodeCheckpointsBuilder,
|
|
17
|
-
} from '
|
|
16
|
+
} from '@aztec/validator-client';
|
|
18
17
|
|
|
19
18
|
/**
|
|
20
19
|
* A fake CheckpointBuilder for testing that implements the same interface as the real one.
|
|
@@ -190,6 +189,12 @@ export class MockCheckpointsBuilder implements FunctionsOf<FullNodeCheckpointsBu
|
|
|
190
189
|
constants: CheckpointGlobalVariables;
|
|
191
190
|
l1ToL2Messages: Fr[];
|
|
192
191
|
}> = [];
|
|
192
|
+
public openCheckpointCalls: Array<{
|
|
193
|
+
checkpointNumber: CheckpointNumber;
|
|
194
|
+
constants: CheckpointGlobalVariables;
|
|
195
|
+
l1ToL2Messages: Fr[];
|
|
196
|
+
existingBlocks: L2BlockNew[];
|
|
197
|
+
}> = [];
|
|
193
198
|
public updateConfigCalls: Array<Partial<FullNodeBlockBuilderConfig>> = [];
|
|
194
199
|
|
|
195
200
|
/**
|
|
@@ -218,6 +223,15 @@ export class MockCheckpointsBuilder implements FunctionsOf<FullNodeCheckpointsBu
|
|
|
218
223
|
return this.checkpointBuilder;
|
|
219
224
|
}
|
|
220
225
|
|
|
226
|
+
getConfig(): FullNodeBlockBuilderConfig {
|
|
227
|
+
return {
|
|
228
|
+
l1GenesisTime: 0n,
|
|
229
|
+
slotDuration: 24,
|
|
230
|
+
l1ChainId: 1,
|
|
231
|
+
rollupVersion: 1,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
221
235
|
updateConfig(config: Partial<FullNodeBlockBuilderConfig>): void {
|
|
222
236
|
this.updateConfigCalls.push(config);
|
|
223
237
|
}
|
|
@@ -238,10 +252,28 @@ export class MockCheckpointsBuilder implements FunctionsOf<FullNodeCheckpointsBu
|
|
|
238
252
|
return Promise.resolve(this.checkpointBuilder as unknown as CheckpointBuilder);
|
|
239
253
|
}
|
|
240
254
|
|
|
255
|
+
openCheckpoint(
|
|
256
|
+
checkpointNumber: CheckpointNumber,
|
|
257
|
+
constants: CheckpointGlobalVariables,
|
|
258
|
+
l1ToL2Messages: Fr[],
|
|
259
|
+
_fork: unknown,
|
|
260
|
+
existingBlocks: L2BlockNew[] = [],
|
|
261
|
+
): Promise<CheckpointBuilder> {
|
|
262
|
+
this.openCheckpointCalls.push({ checkpointNumber, constants, l1ToL2Messages, existingBlocks });
|
|
263
|
+
|
|
264
|
+
if (!this.checkpointBuilder) {
|
|
265
|
+
// Auto-create a builder if none was set
|
|
266
|
+
this.checkpointBuilder = new MockCheckpointBuilder(constants, checkpointNumber);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return Promise.resolve(this.checkpointBuilder as unknown as CheckpointBuilder);
|
|
270
|
+
}
|
|
271
|
+
|
|
241
272
|
/** Reset for reuse in another test */
|
|
242
273
|
reset(): void {
|
|
243
274
|
this.checkpointBuilder = undefined;
|
|
244
275
|
this.startCheckpointCalls = [];
|
|
276
|
+
this.openCheckpointCalls = [];
|
|
245
277
|
this.updateConfigCalls = [];
|
|
246
278
|
}
|
|
247
279
|
}
|
package/src/test/utils.ts
CHANGED
|
@@ -8,16 +8,10 @@ import { Signature } from '@aztec/foundation/eth-signature';
|
|
|
8
8
|
import type { P2P } from '@aztec/p2p';
|
|
9
9
|
import { PublicDataWrite } from '@aztec/stdlib/avm';
|
|
10
10
|
import { CommitteeAttestation, L2BlockNew } from '@aztec/stdlib/block';
|
|
11
|
-
import {
|
|
11
|
+
import { BlockProposal, CheckpointAttestation, CheckpointProposal, ConsensusPayload } from '@aztec/stdlib/p2p';
|
|
12
12
|
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
13
13
|
import { makeAppendOnlyTreeSnapshot, mockTxForRollup } from '@aztec/stdlib/testing';
|
|
14
|
-
import {
|
|
15
|
-
BlockHeader,
|
|
16
|
-
ContentCommitment,
|
|
17
|
-
GlobalVariables,
|
|
18
|
-
type Tx,
|
|
19
|
-
makeProcessedTxFromPrivateOnlyTx,
|
|
20
|
-
} from '@aztec/stdlib/tx';
|
|
14
|
+
import { BlockHeader, GlobalVariables, type Tx, makeProcessedTxFromPrivateOnlyTx } from '@aztec/stdlib/tx';
|
|
21
15
|
|
|
22
16
|
import type { MockProxy } from 'jest-mock-extended';
|
|
23
17
|
|
|
@@ -77,15 +71,15 @@ export function createMockSignatures(signer: Secp256k1Signer): CommitteeAttestat
|
|
|
77
71
|
|
|
78
72
|
/**
|
|
79
73
|
* Creates a CheckpointHeader from an L2BlockNew for testing purposes.
|
|
80
|
-
* Uses mock values for
|
|
81
|
-
* L2BlockNew doesn't have these fields.
|
|
74
|
+
* Uses mock values for blockHeadersHash, blobsHash and inHash since L2BlockNew doesn't have these fields.
|
|
82
75
|
*/
|
|
83
76
|
function createCheckpointHeaderFromBlock(block: L2BlockNew): CheckpointHeader {
|
|
84
77
|
const gv = block.header.globalVariables;
|
|
85
78
|
return new CheckpointHeader(
|
|
86
79
|
block.header.lastArchive.root,
|
|
87
80
|
Fr.random(), // blockHeadersHash - mock value for testing
|
|
88
|
-
|
|
81
|
+
Fr.random(), // blobsHash - mock value for testing
|
|
82
|
+
Fr.random(), // inHash - mock value for testing
|
|
89
83
|
gv.slotNumber,
|
|
90
84
|
gv.timestamp,
|
|
91
85
|
gv.coinbase,
|
|
@@ -99,23 +93,49 @@ function createCheckpointHeaderFromBlock(block: L2BlockNew): CheckpointHeader {
|
|
|
99
93
|
* Creates a block proposal from a block and signature
|
|
100
94
|
*/
|
|
101
95
|
export function createBlockProposal(block: L2BlockNew, signature: Signature): BlockProposal {
|
|
102
|
-
const checkpointHeader = createCheckpointHeaderFromBlock(block);
|
|
103
|
-
const consensusPayload = new ConsensusPayload(checkpointHeader, block.archive.root);
|
|
104
96
|
const txHashes = block.body.txEffects.map(tx => tx.txHash);
|
|
105
|
-
return new BlockProposal(
|
|
97
|
+
return new BlockProposal(
|
|
98
|
+
block.header,
|
|
99
|
+
block.indexWithinCheckpoint,
|
|
100
|
+
Fr.ZERO, // inHash - using zero for testing
|
|
101
|
+
block.archive.root,
|
|
102
|
+
txHashes,
|
|
103
|
+
signature,
|
|
104
|
+
);
|
|
106
105
|
}
|
|
107
106
|
|
|
108
107
|
/**
|
|
109
|
-
* Creates a
|
|
108
|
+
* Creates a checkpoint proposal from a block and signature
|
|
109
|
+
*/
|
|
110
|
+
export function createCheckpointProposal(
|
|
111
|
+
block: L2BlockNew,
|
|
112
|
+
checkpointSignature: Signature,
|
|
113
|
+
blockSignature?: Signature,
|
|
114
|
+
): CheckpointProposal {
|
|
115
|
+
const txHashes = block.body.txEffects.map(tx => tx.txHash);
|
|
116
|
+
const checkpointHeader = createCheckpointHeaderFromBlock(block);
|
|
117
|
+
return new CheckpointProposal(checkpointHeader, block.archive.root, checkpointSignature, {
|
|
118
|
+
blockHeader: block.header,
|
|
119
|
+
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
120
|
+
txHashes,
|
|
121
|
+
signature: blockSignature ?? checkpointSignature, // Use checkpoint signature as block signature if not provided
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Creates a checkpoint attestation from a block and signature.
|
|
110
127
|
* Note: We manually set the sender since we use random signatures in tests.
|
|
111
128
|
* In production, the sender is recovered from the signature.
|
|
112
129
|
*/
|
|
113
|
-
export function
|
|
130
|
+
export function createCheckpointAttestation(
|
|
131
|
+
block: L2BlockNew,
|
|
132
|
+
signature: Signature,
|
|
133
|
+
sender: EthAddress,
|
|
134
|
+
): CheckpointAttestation {
|
|
114
135
|
const checkpointHeader = createCheckpointHeaderFromBlock(block);
|
|
115
|
-
const
|
|
116
|
-
const attestation = new
|
|
136
|
+
const payload = new ConsensusPayload(checkpointHeader, block.archive.root);
|
|
137
|
+
const attestation = new CheckpointAttestation(payload, signature, signature);
|
|
117
138
|
// Set sender directly for testing (bypasses signature recovery)
|
|
118
|
-
|
|
119
139
|
(attestation as any).sender = sender;
|
|
120
140
|
return attestation;
|
|
121
141
|
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
2
|
-
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
|
-
import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
4
|
-
import { LightweightCheckpointBuilder } from '@aztec/prover-client/light';
|
|
5
|
-
import { PublicProcessor } from '@aztec/simulator/server';
|
|
6
|
-
import { L2BlockNew } from '@aztec/stdlib/block';
|
|
7
|
-
import { Checkpoint } from '@aztec/stdlib/checkpoint';
|
|
8
|
-
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
9
|
-
import { Gas } from '@aztec/stdlib/gas';
|
|
10
|
-
import { type FullNodeBlockBuilderConfig, type MerkleTreeWriteOperations, type PublicProcessorLimits } from '@aztec/stdlib/interfaces/server';
|
|
11
|
-
import { type CheckpointGlobalVariables, type FailedTx, GlobalVariables, Tx } from '@aztec/stdlib/tx';
|
|
12
|
-
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
13
|
-
export interface BuildBlockInCheckpointResult {
|
|
14
|
-
block: L2BlockNew;
|
|
15
|
-
publicGas: Gas;
|
|
16
|
-
publicProcessorDuration: number;
|
|
17
|
-
numTxs: number;
|
|
18
|
-
failedTxs: FailedTx[];
|
|
19
|
-
blockBuildingTimer: Timer;
|
|
20
|
-
usedTxs: Tx[];
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Builder for a single checkpoint. Handles building blocks within the checkpoint
|
|
24
|
-
* and completing it.
|
|
25
|
-
*/
|
|
26
|
-
export declare class CheckpointBuilder {
|
|
27
|
-
private checkpointBuilder;
|
|
28
|
-
private fork;
|
|
29
|
-
private config;
|
|
30
|
-
private contractDataSource;
|
|
31
|
-
private dateProvider;
|
|
32
|
-
private telemetryClient;
|
|
33
|
-
constructor(checkpointBuilder: LightweightCheckpointBuilder, fork: MerkleTreeWriteOperations, config: FullNodeBlockBuilderConfig, contractDataSource: ContractDataSource, dateProvider: DateProvider, telemetryClient: TelemetryClient);
|
|
34
|
-
getConstantData(): CheckpointGlobalVariables;
|
|
35
|
-
/**
|
|
36
|
-
* Builds a single block within this checkpoint.
|
|
37
|
-
*/
|
|
38
|
-
buildBlock(pendingTxs: Iterable<Tx> | AsyncIterable<Tx>, blockNumber: BlockNumber, timestamp: bigint, opts: PublicProcessorLimits): Promise<BuildBlockInCheckpointResult>;
|
|
39
|
-
/** Completes the checkpoint and returns it. */
|
|
40
|
-
completeCheckpoint(): Promise<Checkpoint>;
|
|
41
|
-
/** Gets the checkpoint currently in progress. */
|
|
42
|
-
getCheckpoint(): Promise<Checkpoint>;
|
|
43
|
-
protected makeBlockBuilderDeps(globalVariables: GlobalVariables, fork: MerkleTreeWriteOperations): Promise<{
|
|
44
|
-
processor: PublicProcessor;
|
|
45
|
-
validator: import("@aztec/stdlib/interfaces/server").PublicProcessorValidator;
|
|
46
|
-
}>;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Factory for creating checkpoint builders.
|
|
50
|
-
*/
|
|
51
|
-
export declare class FullNodeCheckpointsBuilder {
|
|
52
|
-
private config;
|
|
53
|
-
private contractDataSource;
|
|
54
|
-
private dateProvider;
|
|
55
|
-
private telemetryClient;
|
|
56
|
-
constructor(config: FullNodeBlockBuilderConfig, contractDataSource: ContractDataSource, dateProvider: DateProvider, telemetryClient?: TelemetryClient);
|
|
57
|
-
updateConfig(config: Partial<FullNodeBlockBuilderConfig>): void;
|
|
58
|
-
/**
|
|
59
|
-
* Starts a new checkpoint and returns a CheckpointBuilder to build blocks within it.
|
|
60
|
-
*/
|
|
61
|
-
startCheckpoint(checkpointNumber: CheckpointNumber, constants: CheckpointGlobalVariables, l1ToL2Messages: Fr[], fork: MerkleTreeWriteOperations): Promise<CheckpointBuilder>;
|
|
62
|
-
}
|
|
63
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludF9idWlsZGVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VxdWVuY2VyL2NoZWNrcG9pbnRfYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsV0FBVyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFaEYsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBR3BELE9BQU8sRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFXLE1BQU0seUJBQXlCLENBQUM7QUFFdkUsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDMUUsT0FBTyxFQUdMLGVBQWUsRUFFaEIsTUFBTSx5QkFBeUIsQ0FBQztBQUNqQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sS0FBSyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakUsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3hDLE9BQU8sRUFDTCxLQUFLLDBCQUEwQixFQUUvQixLQUFLLHlCQUF5QixFQUM5QixLQUFLLHFCQUFxQixFQUMzQixNQUFNLGlDQUFpQyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxLQUFLLHlCQUF5QixFQUFFLEtBQUssUUFBUSxFQUFFLGVBQWUsRUFBRSxFQUFFLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN0RyxPQUFPLEVBQUUsS0FBSyxlQUFlLEVBQXNCLE1BQU0seUJBQXlCLENBQUM7QUFNbkYsTUFBTSxXQUFXLDRCQUE0QjtJQUMzQyxLQUFLLEVBQUUsVUFBVSxDQUFDO0lBQ2xCLFNBQVMsRUFBRSxHQUFHLENBQUM7SUFDZix1QkFBdUIsRUFBRSxNQUFNLENBQUM7SUFDaEMsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUNmLFNBQVMsRUFBRSxRQUFRLEVBQUUsQ0FBQztJQUN0QixrQkFBa0IsRUFBRSxLQUFLLENBQUM7SUFDMUIsT0FBTyxFQUFFLEVBQUUsRUFBRSxDQUFDO0NBQ2Y7QUFFRDs7O0dBR0c7QUFDSCxxQkFBYSxpQkFBaUI7SUFFMUIsT0FBTyxDQUFDLGlCQUFpQjtJQUN6QixPQUFPLENBQUMsSUFBSTtJQUNaLE9BQU8sQ0FBQyxNQUFNO0lBQ2QsT0FBTyxDQUFDLGtCQUFrQjtJQUMxQixPQUFPLENBQUMsWUFBWTtJQUNwQixPQUFPLENBQUMsZUFBZTtJQU56QixZQUNVLGlCQUFpQixFQUFFLDRCQUE0QixFQUMvQyxJQUFJLEVBQUUseUJBQXlCLEVBQy9CLE1BQU0sRUFBRSwwQkFBMEIsRUFDbEMsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQ3RDLFlBQVksRUFBRSxZQUFZLEVBQzFCLGVBQWUsRUFBRSxlQUFlLEVBQ3RDO0lBRUosZUFBZSxJQUFJLHlCQUF5QixDQUUzQztJQUVEOztPQUVHO0lBQ0csVUFBVSxDQUNkLFVBQVUsRUFBRSxRQUFRLENBQUMsRUFBRSxDQUFDLEdBQUcsYUFBYSxDQUFDLEVBQUUsQ0FBQyxFQUM1QyxXQUFXLEVBQUUsV0FBVyxFQUN4QixTQUFTLEVBQUUsTUFBTSxFQUNqQixJQUFJLEVBQUUscUJBQXFCLEdBQzFCLE9BQU8sQ0FBQyw0QkFBNEIsQ0FBQyxDQXdDdkM7SUFFRCwrQ0FBK0M7SUFDekMsa0JBQWtCLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQVU5QztJQUVELGlEQUFpRDtJQUNqRCxhQUFhLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUVuQztJQUVELFVBQWdCLG9CQUFvQixDQUFDLGVBQWUsRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLHlCQUF5Qjs7O09Ba0NyRztDQUNGO0FBRUQ7O0dBRUc7QUFDSCxxQkFBYSwwQkFBMEI7SUFFbkMsT0FBTyxDQUFDLE1BQU07SUFDZCxPQUFPLENBQUMsa0JBQWtCO0lBQzFCLE9BQU8sQ0FBQyxZQUFZO0lBQ3BCLE9BQU8sQ0FBQyxlQUFlO0lBSnpCLFlBQ1UsTUFBTSxFQUFFLDBCQUEwQixFQUNsQyxrQkFBa0IsRUFBRSxrQkFBa0IsRUFDdEMsWUFBWSxFQUFFLFlBQVksRUFDMUIsZUFBZSxHQUFFLGVBQXNDLEVBQzdEO0lBRUcsWUFBWSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsMEJBQTBCLENBQUMsUUFFOUQ7SUFFRDs7T0FFRztJQUNHLGVBQWUsQ0FDbkIsZ0JBQWdCLEVBQUUsZ0JBQWdCLEVBQ2xDLFNBQVMsRUFBRSx5QkFBeUIsRUFDcEMsY0FBYyxFQUFFLEVBQUUsRUFBRSxFQUNwQixJQUFJLEVBQUUseUJBQXlCLEdBQzlCLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQTJCNUI7Q0FDRiJ9
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"checkpoint_builder.d.ts","sourceRoot":"","sources":["../../src/sequencer/checkpoint_builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEhF,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAGpD,OAAO,EAAE,YAAY,EAAE,KAAK,EAAW,MAAM,yBAAyB,CAAC;AAEvE,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAGL,eAAe,EAEhB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EACL,KAAK,0BAA0B,EAE/B,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC3B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,yBAAyB,EAAE,KAAK,QAAQ,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtG,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAMnF,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,GAAG,CAAC;IACf,uBAAuB,EAAE,MAAM,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,kBAAkB,EAAE,KAAK,CAAC;IAC1B,OAAO,EAAE,EAAE,EAAE,CAAC;CACf;AAED;;;GAGG;AACH,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,eAAe;IANzB,YACU,iBAAiB,EAAE,4BAA4B,EAC/C,IAAI,EAAE,yBAAyB,EAC/B,MAAM,EAAE,0BAA0B,EAClC,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,YAAY,EAC1B,eAAe,EAAE,eAAe,EACtC;IAEJ,eAAe,IAAI,yBAAyB,CAE3C;IAED;;OAEG;IACG,UAAU,CACd,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC,EAC5C,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,4BAA4B,CAAC,CAwCvC;IAED,+CAA+C;IACzC,kBAAkB,IAAI,OAAO,CAAC,UAAU,CAAC,CAU9C;IAED,iDAAiD;IACjD,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CAEnC;IAED,UAAgB,oBAAoB,CAAC,eAAe,EAAE,eAAe,EAAE,IAAI,EAAE,yBAAyB;;;OAkCrG;CACF;AAED;;GAEG;AACH,qBAAa,0BAA0B;IAEnC,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,eAAe;IAJzB,YACU,MAAM,EAAE,0BAA0B,EAClC,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,YAAY,EAC1B,eAAe,GAAE,eAAsC,EAC7D;IAEG,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,0BAA0B,CAAC,QAE9D;IAED;;OAEG;IACG,eAAe,CACnB,gBAAgB,EAAE,gBAAgB,EAClC,SAAS,EAAE,yBAAyB,EACpC,cAAc,EAAE,EAAE,EAAE,EACpB,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,iBAAiB,CAAC,CA2B5B;CACF"}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { MerkleTreeId } from '@aztec/aztec.js/trees';
|
|
2
|
-
import { merge, pick } from '@aztec/foundation/collection';
|
|
3
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
4
|
-
import { bufferToHex } from '@aztec/foundation/string';
|
|
5
|
-
import { Timer, elapsed } from '@aztec/foundation/timer';
|
|
6
|
-
import { getDefaultAllowedSetupFunctions } from '@aztec/p2p/msg_validators';
|
|
7
|
-
import { LightweightCheckpointBuilder } from '@aztec/prover-client/light';
|
|
8
|
-
import { GuardedMerkleTreeOperations, PublicContractsDB, PublicProcessor, createPublicTxSimulatorForBlockBuilding } from '@aztec/simulator/server';
|
|
9
|
-
import { Gas } from '@aztec/stdlib/gas';
|
|
10
|
-
import { FullNodeBlockBuilderConfigKeys } from '@aztec/stdlib/interfaces/server';
|
|
11
|
-
import { GlobalVariables } from '@aztec/stdlib/tx';
|
|
12
|
-
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
13
|
-
import { createValidatorForBlockBuilding } from '../tx_validator/tx_validator_factory.js';
|
|
14
|
-
const log = createLogger('checkpoint-builder');
|
|
15
|
-
/**
|
|
16
|
-
* Builder for a single checkpoint. Handles building blocks within the checkpoint
|
|
17
|
-
* and completing it.
|
|
18
|
-
*/ export class CheckpointBuilder {
|
|
19
|
-
checkpointBuilder;
|
|
20
|
-
fork;
|
|
21
|
-
config;
|
|
22
|
-
contractDataSource;
|
|
23
|
-
dateProvider;
|
|
24
|
-
telemetryClient;
|
|
25
|
-
constructor(checkpointBuilder, fork, config, contractDataSource, dateProvider, telemetryClient){
|
|
26
|
-
this.checkpointBuilder = checkpointBuilder;
|
|
27
|
-
this.fork = fork;
|
|
28
|
-
this.config = config;
|
|
29
|
-
this.contractDataSource = contractDataSource;
|
|
30
|
-
this.dateProvider = dateProvider;
|
|
31
|
-
this.telemetryClient = telemetryClient;
|
|
32
|
-
}
|
|
33
|
-
getConstantData() {
|
|
34
|
-
return this.checkpointBuilder.constants;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Builds a single block within this checkpoint.
|
|
38
|
-
*/ async buildBlock(pendingTxs, blockNumber, timestamp, opts) {
|
|
39
|
-
const blockBuildingTimer = new Timer();
|
|
40
|
-
const slot = this.checkpointBuilder.constants.slotNumber;
|
|
41
|
-
log.verbose(`Building block ${blockNumber} for slot ${slot} within checkpoint`, {
|
|
42
|
-
slot,
|
|
43
|
-
blockNumber,
|
|
44
|
-
...opts
|
|
45
|
-
});
|
|
46
|
-
const constants = this.checkpointBuilder.constants;
|
|
47
|
-
const globalVariables = GlobalVariables.from({
|
|
48
|
-
chainId: constants.chainId,
|
|
49
|
-
version: constants.version,
|
|
50
|
-
blockNumber,
|
|
51
|
-
slotNumber: constants.slotNumber,
|
|
52
|
-
timestamp,
|
|
53
|
-
coinbase: constants.coinbase,
|
|
54
|
-
feeRecipient: constants.feeRecipient,
|
|
55
|
-
gasFees: constants.gasFees
|
|
56
|
-
});
|
|
57
|
-
const { processor, validator } = await this.makeBlockBuilderDeps(globalVariables, this.fork);
|
|
58
|
-
const [publicProcessorDuration, [processedTxs, failedTxs, usedTxs]] = await elapsed(()=>processor.process(pendingTxs, opts, validator));
|
|
59
|
-
// Add block to checkpoint
|
|
60
|
-
const block = await this.checkpointBuilder.addBlock(globalVariables, processedTxs);
|
|
61
|
-
// How much public gas was processed
|
|
62
|
-
const publicGas = processedTxs.reduce((acc, tx)=>acc.add(tx.gasUsed.publicGas), Gas.empty());
|
|
63
|
-
const res = {
|
|
64
|
-
block,
|
|
65
|
-
publicGas,
|
|
66
|
-
publicProcessorDuration,
|
|
67
|
-
numTxs: processedTxs.length,
|
|
68
|
-
failedTxs,
|
|
69
|
-
blockBuildingTimer,
|
|
70
|
-
usedTxs
|
|
71
|
-
};
|
|
72
|
-
log.debug('Built block within checkpoint', res.block.header);
|
|
73
|
-
return res;
|
|
74
|
-
}
|
|
75
|
-
/** Completes the checkpoint and returns it. */ async completeCheckpoint() {
|
|
76
|
-
const checkpoint = await this.checkpointBuilder.completeCheckpoint();
|
|
77
|
-
log.verbose(`Completed checkpoint ${checkpoint.number}`, {
|
|
78
|
-
checkpointNumber: checkpoint.number,
|
|
79
|
-
numBlocks: checkpoint.blocks.length,
|
|
80
|
-
archiveRoot: checkpoint.archive.root.toString()
|
|
81
|
-
});
|
|
82
|
-
return checkpoint;
|
|
83
|
-
}
|
|
84
|
-
/** Gets the checkpoint currently in progress. */ getCheckpoint() {
|
|
85
|
-
return this.checkpointBuilder.clone().completeCheckpoint();
|
|
86
|
-
}
|
|
87
|
-
async makeBlockBuilderDeps(globalVariables, fork) {
|
|
88
|
-
const txPublicSetupAllowList = this.config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions();
|
|
89
|
-
const contractsDB = new PublicContractsDB(this.contractDataSource);
|
|
90
|
-
const guardedFork = new GuardedMerkleTreeOperations(fork);
|
|
91
|
-
const publicTxSimulator = createPublicTxSimulatorForBlockBuilding(guardedFork, contractsDB, globalVariables, this.telemetryClient);
|
|
92
|
-
const processor = new PublicProcessor(globalVariables, guardedFork, contractsDB, publicTxSimulator, this.dateProvider, this.telemetryClient, undefined, this.config);
|
|
93
|
-
const validator = createValidatorForBlockBuilding(fork, this.contractDataSource, globalVariables, txPublicSetupAllowList);
|
|
94
|
-
return {
|
|
95
|
-
processor,
|
|
96
|
-
validator
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Factory for creating checkpoint builders.
|
|
102
|
-
*/ export class FullNodeCheckpointsBuilder {
|
|
103
|
-
config;
|
|
104
|
-
contractDataSource;
|
|
105
|
-
dateProvider;
|
|
106
|
-
telemetryClient;
|
|
107
|
-
constructor(config, contractDataSource, dateProvider, telemetryClient = getTelemetryClient()){
|
|
108
|
-
this.config = config;
|
|
109
|
-
this.contractDataSource = contractDataSource;
|
|
110
|
-
this.dateProvider = dateProvider;
|
|
111
|
-
this.telemetryClient = telemetryClient;
|
|
112
|
-
}
|
|
113
|
-
updateConfig(config) {
|
|
114
|
-
this.config = merge(this.config, pick(config, ...FullNodeBlockBuilderConfigKeys));
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Starts a new checkpoint and returns a CheckpointBuilder to build blocks within it.
|
|
118
|
-
*/ async startCheckpoint(checkpointNumber, constants, l1ToL2Messages, fork) {
|
|
119
|
-
const stateReference = await fork.getStateReference();
|
|
120
|
-
const archiveTree = await fork.getTreeInfo(MerkleTreeId.ARCHIVE);
|
|
121
|
-
log.verbose(`Building checkpoint ${checkpointNumber}`, {
|
|
122
|
-
checkpointNumber,
|
|
123
|
-
msgCount: l1ToL2Messages.length,
|
|
124
|
-
initialStateReference: stateReference.toInspect(),
|
|
125
|
-
initialArchiveRoot: bufferToHex(archiveTree.root),
|
|
126
|
-
constants
|
|
127
|
-
});
|
|
128
|
-
const lightweightBuilder = await LightweightCheckpointBuilder.startNewCheckpoint(checkpointNumber, constants, l1ToL2Messages, fork);
|
|
129
|
-
return new CheckpointBuilder(lightweightBuilder, fork, this.config, this.contractDataSource, this.dateProvider, this.telemetryClient);
|
|
130
|
-
}
|
|
131
|
-
}
|