@aztec/sequencer-client 2.0.3 → 2.1.0-rc.2
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.map +1 -1
- package/dest/client/sequencer-client.js +7 -4
- package/dest/config.d.ts +2 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +2 -0
- package/dest/publisher/config.d.ts +2 -4
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +7 -10
- package/dest/publisher/index.d.ts +1 -1
- package/dest/publisher/index.d.ts.map +1 -1
- package/dest/publisher/index.js +1 -1
- package/dest/publisher/sequencer-publisher-factory.d.ts +5 -1
- package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-factory.js +8 -1
- package/dest/publisher/sequencer-publisher.d.ts +14 -20
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +53 -58
- package/dest/sequencer/errors.d.ts +11 -0
- package/dest/sequencer/errors.d.ts.map +1 -0
- package/dest/sequencer/errors.js +15 -0
- package/dest/sequencer/metrics.d.ts +5 -17
- package/dest/sequencer/metrics.d.ts.map +1 -1
- package/dest/sequencer/metrics.js +22 -88
- package/dest/sequencer/sequencer.d.ts +4 -3
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +27 -21
- package/dest/sequencer/timetable.d.ts +0 -6
- package/dest/sequencer/timetable.d.ts.map +1 -1
- package/dest/sequencer/timetable.js +2 -9
- package/dest/sequencer/utils.d.ts +10 -24
- package/dest/sequencer/utils.d.ts.map +1 -1
- package/dest/sequencer/utils.js +9 -24
- package/package.json +28 -28
- package/src/client/sequencer-client.ts +6 -2
- package/src/config.ts +3 -0
- package/src/publisher/config.ts +13 -11
- package/src/publisher/index.ts +1 -1
- package/src/publisher/sequencer-publisher-factory.ts +12 -2
- package/src/publisher/sequencer-publisher.ts +77 -77
- package/src/sequencer/errors.ts +21 -0
- package/src/sequencer/metrics.ts +24 -100
- package/src/sequencer/sequencer.ts +51 -46
- package/src/sequencer/timetable.ts +2 -13
- package/src/sequencer/utils.ts +10 -24
|
@@ -4,22 +4,16 @@ import { FormattedViemError, MULTI_CALL_3_ADDRESS, Multicall3, RollupContract, f
|
|
|
4
4
|
import { sumBigint } from '@aztec/foundation/bigint';
|
|
5
5
|
import { toHex as toPaddedHex } from '@aztec/foundation/bigint-buffer';
|
|
6
6
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
7
|
+
import { Signature } from '@aztec/foundation/eth-signature';
|
|
7
8
|
import { createLogger } from '@aztec/foundation/log';
|
|
8
9
|
import { bufferToHex } from '@aztec/foundation/string';
|
|
9
10
|
import { Timer } from '@aztec/foundation/timer';
|
|
10
11
|
import { EmpireBaseAbi, ErrorsAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
11
12
|
import { encodeSlashConsensusVotes } from '@aztec/slasher';
|
|
12
|
-
import { CommitteeAttestation } from '@aztec/stdlib/block';
|
|
13
|
-
import { ConsensusPayload, SignatureDomainSeparator, getHashedSignaturePayload } from '@aztec/stdlib/p2p';
|
|
13
|
+
import { CommitteeAttestation, CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
|
|
14
14
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
15
|
-
import pick from 'lodash.pick';
|
|
16
15
|
import { encodeFunctionData, toHex } from 'viem';
|
|
17
16
|
import { SequencerPublisherMetrics } from './sequencer-publisher-metrics.js';
|
|
18
|
-
export var SignalType = /*#__PURE__*/ function(SignalType) {
|
|
19
|
-
SignalType[SignalType["GOVERNANCE"] = 0] = "GOVERNANCE";
|
|
20
|
-
SignalType[SignalType["SLASHING"] = 1] = "SLASHING";
|
|
21
|
-
return SignalType;
|
|
22
|
-
}({});
|
|
23
17
|
export const Actions = [
|
|
24
18
|
'invalidate-by-invalid-attestation',
|
|
25
19
|
'invalidate-by-insufficient-attestations',
|
|
@@ -40,7 +34,7 @@ export class SequencerPublisher {
|
|
|
40
34
|
epochCache;
|
|
41
35
|
governanceLog;
|
|
42
36
|
slashingLog;
|
|
43
|
-
|
|
37
|
+
lastActions;
|
|
44
38
|
log;
|
|
45
39
|
ethereumSlotDuration;
|
|
46
40
|
blobSinkClient;
|
|
@@ -63,14 +57,12 @@ export class SequencerPublisher {
|
|
|
63
57
|
this.interrupted = false;
|
|
64
58
|
this.governanceLog = createLogger('sequencer:publisher:governance');
|
|
65
59
|
this.slashingLog = createLogger('sequencer:publisher:slashing');
|
|
66
|
-
this.
|
|
67
|
-
[0]: 0n,
|
|
68
|
-
[1]: 0n
|
|
69
|
-
};
|
|
70
|
-
this.log = createLogger('sequencer:publisher');
|
|
60
|
+
this.lastActions = {};
|
|
71
61
|
this.requests = [];
|
|
62
|
+
this.log = deps.log ?? createLogger('sequencer:publisher');
|
|
72
63
|
this.ethereumSlotDuration = BigInt(config.ethereumSlotDuration);
|
|
73
64
|
this.epochCache = deps.epochCache;
|
|
65
|
+
this.lastActions = deps.lastActions;
|
|
74
66
|
this.blobSinkClient = deps.blobSinkClient ?? createBlobSinkClient(config, {
|
|
75
67
|
logger: createLogger('sequencer:blob-sink:client')
|
|
76
68
|
});
|
|
@@ -148,7 +140,7 @@ export class SequencerPublisher {
|
|
|
148
140
|
const gasLimit = gasLimits.length > 0 ? sumBigint(gasLimits) : undefined; // sum
|
|
149
141
|
const txTimeoutAts = gasConfigs.map((g)=>g?.txTimeoutAt).filter((g)=>g !== undefined);
|
|
150
142
|
const txTimeoutAt = txTimeoutAts.length > 0 ? new Date(Math.min(...txTimeoutAts.map((g)=>g.getTime()))) : undefined; // earliest
|
|
151
|
-
const
|
|
143
|
+
const txConfig = {
|
|
152
144
|
gasLimit,
|
|
153
145
|
txTimeoutAt
|
|
154
146
|
};
|
|
@@ -157,9 +149,10 @@ export class SequencerPublisher {
|
|
|
157
149
|
validRequests.sort((a, b)=>compareActions(a.action, b.action));
|
|
158
150
|
try {
|
|
159
151
|
this.log.debug('Forwarding transactions', {
|
|
160
|
-
validRequests: validRequests.map((request)=>request.action)
|
|
152
|
+
validRequests: validRequests.map((request)=>request.action),
|
|
153
|
+
txConfig
|
|
161
154
|
});
|
|
162
|
-
const result = await Multicall3.forward(validRequests.map((request)=>request.request), this.l1TxUtils,
|
|
155
|
+
const result = await Multicall3.forward(validRequests.map((request)=>request.request), this.l1TxUtils, txConfig, blobConfig, this.rollupContract.address, this.log);
|
|
163
156
|
const { successfulActions = [], failedActions = [] } = this.callbackBundledTransactions(validRequests, result);
|
|
164
157
|
return {
|
|
165
158
|
result,
|
|
@@ -241,8 +234,9 @@ export class SequencerPublisher {
|
|
|
241
234
|
};
|
|
242
235
|
const args = [
|
|
243
236
|
header.toViem(),
|
|
244
|
-
|
|
237
|
+
CommitteeAttestationsAndSigners.empty().getPackedAttestations(),
|
|
245
238
|
[],
|
|
239
|
+
Signature.empty().toViemSignature(),
|
|
246
240
|
`0x${'0'.repeat(64)}`,
|
|
247
241
|
header.contentCommitment.blobsHash.toString(),
|
|
248
242
|
flags
|
|
@@ -350,10 +344,11 @@ export class SequencerPublisher {
|
|
|
350
344
|
reason
|
|
351
345
|
};
|
|
352
346
|
this.log.debug(`Simulating invalidate block ${block.blockNumber}`, logData);
|
|
347
|
+
const attestationsAndSigners = new CommitteeAttestationsAndSigners(attestations).getPackedAttestations();
|
|
353
348
|
if (reason === 'invalid-attestation') {
|
|
354
|
-
return this.rollupContract.buildInvalidateBadAttestationRequest(block.blockNumber,
|
|
349
|
+
return this.rollupContract.buildInvalidateBadAttestationRequest(block.blockNumber, attestationsAndSigners, committee, validationResult.invalidIndex);
|
|
355
350
|
} else if (reason === 'insufficient-attestations') {
|
|
356
|
-
return this.rollupContract.buildInvalidateInsufficientAttestationsRequest(block.blockNumber,
|
|
351
|
+
return this.rollupContract.buildInvalidateInsufficientAttestationsRequest(block.blockNumber, attestationsAndSigners, committee);
|
|
357
352
|
} else {
|
|
358
353
|
const _ = reason;
|
|
359
354
|
throw new Error(`Unknown reason for invalidation`);
|
|
@@ -367,45 +362,41 @@ export class SequencerPublisher {
|
|
|
367
362
|
* @param block - The block to propose
|
|
368
363
|
* @param attestationData - The block's attestation data
|
|
369
364
|
*
|
|
370
|
-
*/ async validateBlockForSubmission(block,
|
|
371
|
-
digest: Buffer.alloc(32),
|
|
372
|
-
attestations: []
|
|
373
|
-
}, options) {
|
|
365
|
+
*/ async validateBlockForSubmission(block, attestationsAndSigners, attestationsAndSignersSignature, options) {
|
|
374
366
|
const ts = BigInt((await this.l1TxUtils.getBlock()).timestamp + this.ethereumSlotDuration);
|
|
375
367
|
// If we have no attestations, we still need to provide the empty attestations
|
|
376
368
|
// so that the committee is recalculated correctly
|
|
377
|
-
const ignoreSignatures =
|
|
369
|
+
const ignoreSignatures = attestationsAndSigners.attestations.length === 0;
|
|
378
370
|
if (ignoreSignatures) {
|
|
379
371
|
const { committee } = await this.epochCache.getCommittee(block.header.globalVariables.slotNumber.toBigInt());
|
|
380
372
|
if (!committee) {
|
|
381
373
|
this.log.warn(`No committee found for slot ${block.header.globalVariables.slotNumber.toBigInt()}`);
|
|
382
374
|
throw new Error(`No committee found for slot ${block.header.globalVariables.slotNumber.toBigInt()}`);
|
|
383
375
|
}
|
|
384
|
-
|
|
376
|
+
attestationsAndSigners.attestations = committee.map((committeeMember)=>CommitteeAttestation.fromAddress(committeeMember));
|
|
385
377
|
}
|
|
386
378
|
const blobs = await Blob.getBlobsPerBlock(block.body.toBlobFields());
|
|
387
379
|
const blobInput = Blob.getPrefixedEthBlobCommitments(blobs);
|
|
388
|
-
const formattedAttestations = attestationData.attestations.map((attest)=>attest.toViem());
|
|
389
|
-
const signers = attestationData.attestations.filter((attest)=>!attest.signature.isEmpty()).map((attest)=>attest.address.toString());
|
|
390
380
|
const args = [
|
|
391
381
|
{
|
|
392
382
|
header: block.header.toPropose().toViem(),
|
|
393
383
|
archive: toHex(block.archive.root.toBuffer()),
|
|
394
384
|
stateReference: block.header.state.toViem(),
|
|
395
|
-
txHashes: block.body.txEffects.map((txEffect)=>txEffect.txHash.toString()),
|
|
396
385
|
oracleInput: {
|
|
397
386
|
feeAssetPriceModifier: 0n
|
|
398
387
|
}
|
|
399
388
|
},
|
|
400
|
-
|
|
401
|
-
|
|
389
|
+
attestationsAndSigners.getPackedAttestations(),
|
|
390
|
+
attestationsAndSigners.getSigners().map((signer)=>signer.toString()),
|
|
391
|
+
attestationsAndSignersSignature.toViemSignature(),
|
|
402
392
|
blobInput
|
|
403
393
|
];
|
|
404
394
|
await this.simulateProposeTx(args, ts, options);
|
|
405
395
|
return ts;
|
|
406
396
|
}
|
|
407
397
|
async enqueueCastSignalHelper(slotNumber, timestamp, signalType, payload, base, signerAddress, signer) {
|
|
408
|
-
if (this.
|
|
398
|
+
if (this.lastActions[signalType] && this.lastActions[signalType] === slotNumber) {
|
|
399
|
+
this.log.debug(`Skipping duplicate vote cast signal ${signalType} for slot ${slotNumber}`);
|
|
409
400
|
return false;
|
|
410
401
|
}
|
|
411
402
|
if (payload.equals(EthAddress.ZERO)) {
|
|
@@ -420,9 +411,9 @@ export class SequencerPublisher {
|
|
|
420
411
|
if (roundInfo.lastSignalSlot >= slotNumber) {
|
|
421
412
|
return false;
|
|
422
413
|
}
|
|
423
|
-
const cachedLastVote = this.
|
|
424
|
-
this.
|
|
425
|
-
const action = signalType
|
|
414
|
+
const cachedLastVote = this.lastActions[signalType];
|
|
415
|
+
this.lastActions[signalType] = slotNumber;
|
|
416
|
+
const action = signalType;
|
|
426
417
|
const request = await base.createSignalRequestWithSignature(payload.toString(), slotNumber, this.config.l1ChainId, signerAddress.toString(), signer);
|
|
427
418
|
this.log.debug(`Created ${action} request with signature`, {
|
|
428
419
|
request,
|
|
@@ -459,7 +450,7 @@ export class SequencerPublisher {
|
|
|
459
450
|
};
|
|
460
451
|
if (!success) {
|
|
461
452
|
this.log.error(`Signaling in [${action}] for ${payload} at slot ${slotNumber} in round ${round} failed`, logData);
|
|
462
|
-
this.
|
|
453
|
+
this.lastActions[signalType] = cachedLastVote;
|
|
463
454
|
return false;
|
|
464
455
|
} else {
|
|
465
456
|
this.log.info(`Signaling in [${action}] for ${payload} at slot ${slotNumber} in round ${round} succeeded`, logData);
|
|
@@ -475,7 +466,7 @@ export class SequencerPublisher {
|
|
|
475
466
|
* @param timestamp - The timestamp of the slot to cast a signal for.
|
|
476
467
|
* @returns True if the signal was successfully enqueued, false otherwise.
|
|
477
468
|
*/ enqueueGovernanceCastSignal(governancePayload, slotNumber, timestamp, signerAddress, signer) {
|
|
478
|
-
return this.enqueueCastSignalHelper(slotNumber, timestamp,
|
|
469
|
+
return this.enqueueCastSignalHelper(slotNumber, timestamp, 'governance-signal', governancePayload, this.govProposerContract, signerAddress, signer);
|
|
479
470
|
}
|
|
480
471
|
/** Enqueues all slashing actions as returned by the slasher client. */ async enqueueSlashingActions(actions, slotNumber, timestamp, signerAddress, signer) {
|
|
481
472
|
if (actions.length === 0) {
|
|
@@ -493,7 +484,7 @@ export class SequencerPublisher {
|
|
|
493
484
|
this.log.debug(`Enqueuing slashing vote for payload ${action.payload} at slot ${slotNumber}`, {
|
|
494
485
|
signerAddress
|
|
495
486
|
});
|
|
496
|
-
await this.enqueueCastSignalHelper(slotNumber, timestamp,
|
|
487
|
+
await this.enqueueCastSignalHelper(slotNumber, timestamp, 'empire-slashing-signal', action.payload, this.slashingProposerContract, signerAddress, signer);
|
|
497
488
|
break;
|
|
498
489
|
}
|
|
499
490
|
case 'create-empire-payload':
|
|
@@ -569,10 +560,8 @@ export class SequencerPublisher {
|
|
|
569
560
|
*
|
|
570
561
|
* @param block - L2 block to propose.
|
|
571
562
|
* @returns True if the tx has been enqueued, throws otherwise. See #9315
|
|
572
|
-
*/ async enqueueProposeL2Block(block,
|
|
563
|
+
*/ async enqueueProposeL2Block(block, attestationsAndSigners, attestationsAndSignersSignature, opts = {}) {
|
|
573
564
|
const proposedBlockHeader = block.header.toPropose();
|
|
574
|
-
const consensusPayload = ConsensusPayload.fromBlock(block);
|
|
575
|
-
const digest = getHashedSignaturePayload(consensusPayload, SignatureDomainSeparator.blockAttestation);
|
|
576
565
|
const blobs = await Blob.getBlobsPerBlock(block.body.toBlobFields());
|
|
577
566
|
const proposeTxArgs = {
|
|
578
567
|
header: proposedBlockHeader,
|
|
@@ -580,8 +569,8 @@ export class SequencerPublisher {
|
|
|
580
569
|
stateReference: block.header.state,
|
|
581
570
|
body: block.body.toBuffer(),
|
|
582
571
|
blobs,
|
|
583
|
-
|
|
584
|
-
|
|
572
|
+
attestationsAndSigners,
|
|
573
|
+
attestationsAndSignersSignature
|
|
585
574
|
};
|
|
586
575
|
let ts;
|
|
587
576
|
try {
|
|
@@ -589,12 +578,8 @@ export class SequencerPublisher {
|
|
|
589
578
|
// This means that we can avoid the simulation issues in later checks.
|
|
590
579
|
// By simulation issue, I mean the fact that the block.timestamp is equal to the last block, not the next, which
|
|
591
580
|
// make time consistency checks break.
|
|
592
|
-
const attestationData = {
|
|
593
|
-
digest: digest.toBuffer(),
|
|
594
|
-
attestations: attestations ?? []
|
|
595
|
-
};
|
|
596
581
|
// TODO(palla): Check whether we're validating twice, once here and once within addProposeTx, since we call simulateProposeTx in both places.
|
|
597
|
-
ts = await this.validateBlockForSubmission(block,
|
|
582
|
+
ts = await this.validateBlockForSubmission(block, attestationsAndSigners, attestationsAndSignersSignature, opts);
|
|
598
583
|
} catch (err) {
|
|
599
584
|
this.log.error(`Block validation failed. ${err instanceof Error ? err.message : 'No error message'}`, err, {
|
|
600
585
|
...block.getStats(),
|
|
@@ -616,8 +601,10 @@ export class SequencerPublisher {
|
|
|
616
601
|
}
|
|
617
602
|
// We issued the simulation against the rollup contract, so we need to account for the overhead of the multicall3
|
|
618
603
|
const gasLimit = this.l1TxUtils.bumpGasLimit(BigInt(Math.ceil(Number(request.gasUsed) * 64 / 63)));
|
|
604
|
+
const { gasUsed, blockNumber } = request;
|
|
619
605
|
const logData = {
|
|
620
|
-
|
|
606
|
+
gasUsed,
|
|
607
|
+
blockNumber,
|
|
621
608
|
gasLimit,
|
|
622
609
|
opts
|
|
623
610
|
};
|
|
@@ -653,8 +640,14 @@ export class SequencerPublisher {
|
|
|
653
640
|
timestamp,
|
|
654
641
|
gasLimit: undefined
|
|
655
642
|
};
|
|
643
|
+
if (this.lastActions[action] && this.lastActions[action] === slotNumber) {
|
|
644
|
+
this.log.debug(`Skipping duplicate action ${action} for slot ${slotNumber}`);
|
|
645
|
+
return false;
|
|
646
|
+
}
|
|
647
|
+
const cachedLastActionSlot = this.lastActions[action];
|
|
648
|
+
this.lastActions[action] = slotNumber;
|
|
649
|
+
this.log.debug(`Simulating ${action} for slot ${slotNumber}`, logData);
|
|
656
650
|
let gasUsed;
|
|
657
|
-
this.log.debug(`Simulating ${action}`, logData);
|
|
658
651
|
try {
|
|
659
652
|
({ gasUsed } = await this.l1TxUtils.simulate(request, {
|
|
660
653
|
time: timestamp
|
|
@@ -687,6 +680,7 @@ export class SequencerPublisher {
|
|
|
687
680
|
...result,
|
|
688
681
|
...logData
|
|
689
682
|
});
|
|
683
|
+
this.lastActions[action] = cachedLastActionSlot;
|
|
690
684
|
} else {
|
|
691
685
|
this.log.info(`Action ${action} at ${slotNumber} succeeded`, {
|
|
692
686
|
...result,
|
|
@@ -736,9 +730,7 @@ export class SequencerPublisher {
|
|
|
736
730
|
});
|
|
737
731
|
throw new Error('Failed to validate blobs');
|
|
738
732
|
});
|
|
739
|
-
const
|
|
740
|
-
const txHashes = encodedData.txHashes ? encodedData.txHashes.map((txHash)=>txHash.toString()) : [];
|
|
741
|
-
const signers = encodedData.attestations?.filter((attest)=>!attest.signature.isEmpty()).map((attest)=>attest.address.toString());
|
|
733
|
+
const signers = encodedData.attestationsAndSigners.getSigners().map((signer)=>signer.toString());
|
|
742
734
|
const args = [
|
|
743
735
|
{
|
|
744
736
|
header: encodedData.header.toViem(),
|
|
@@ -747,11 +739,11 @@ export class SequencerPublisher {
|
|
|
747
739
|
oracleInput: {
|
|
748
740
|
// We are currently not modifying these. See #9963
|
|
749
741
|
feeAssetPriceModifier: 0n
|
|
750
|
-
}
|
|
751
|
-
txHashes
|
|
742
|
+
}
|
|
752
743
|
},
|
|
753
|
-
|
|
754
|
-
signers
|
|
744
|
+
encodedData.attestationsAndSigners.getPackedAttestations(),
|
|
745
|
+
signers,
|
|
746
|
+
encodedData.attestationsAndSignersSignature.toViemSignature(),
|
|
755
747
|
blobInput
|
|
756
748
|
];
|
|
757
749
|
const { rollupData, simulationResult } = await this.simulateProposeTx(args, timestamp, options);
|
|
@@ -843,13 +835,16 @@ export class SequencerPublisher {
|
|
|
843
835
|
if (success) {
|
|
844
836
|
const endBlock = receipt.blockNumber;
|
|
845
837
|
const inclusionBlocks = Number(endBlock - startBlock);
|
|
838
|
+
const { calldataGas, calldataSize, sender } = stats;
|
|
846
839
|
const publishStats = {
|
|
847
840
|
gasPrice: receipt.effectiveGasPrice,
|
|
848
841
|
gasUsed: receipt.gasUsed,
|
|
849
842
|
blobGasUsed: receipt.blobGasUsed ?? 0n,
|
|
850
843
|
blobDataGas: receipt.blobGasPrice ?? 0n,
|
|
851
844
|
transactionHash: receipt.transactionHash,
|
|
852
|
-
|
|
845
|
+
calldataGas,
|
|
846
|
+
calldataSize,
|
|
847
|
+
sender,
|
|
853
848
|
...block.getStats(),
|
|
854
849
|
eventName: 'rollup-published-to-l1',
|
|
855
850
|
blobCount: encodedData.blobs.length,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SequencerState } from './utils.js';
|
|
2
|
+
export declare class SequencerTooSlowError extends Error {
|
|
3
|
+
readonly proposedState: SequencerState;
|
|
4
|
+
readonly maxAllowedTime: number;
|
|
5
|
+
readonly currentTime: number;
|
|
6
|
+
constructor(proposedState: SequencerState, maxAllowedTime: number, currentTime: number);
|
|
7
|
+
}
|
|
8
|
+
export declare class SequencerInterruptedError extends Error {
|
|
9
|
+
constructor();
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/sequencer/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,qBAAa,qBAAsB,SAAQ,KAAK;aAE5B,aAAa,EAAE,cAAc;aAC7B,cAAc,EAAE,MAAM;aACtB,WAAW,EAAE,MAAM;gBAFnB,aAAa,EAAE,cAAc,EAC7B,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM;CAOtC;AAED,qBAAa,yBAA0B,SAAQ,KAAK;;CAKnD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export class SequencerTooSlowError extends Error {
|
|
2
|
+
proposedState;
|
|
3
|
+
maxAllowedTime;
|
|
4
|
+
currentTime;
|
|
5
|
+
constructor(proposedState, maxAllowedTime, currentTime){
|
|
6
|
+
super(`Too far into slot for ${proposedState} (time into slot ${currentTime}s greater than ${maxAllowedTime}s allowance)`), this.proposedState = proposedState, this.maxAllowedTime = maxAllowedTime, this.currentTime = currentTime;
|
|
7
|
+
this.name = 'SequencerTooSlowError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export class SequencerInterruptedError extends Error {
|
|
11
|
+
constructor(){
|
|
12
|
+
super(`Sequencer was interrupted`);
|
|
13
|
+
this.name = 'SequencerInterruptedError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { EthAddress } from '@aztec/aztec.js';
|
|
2
2
|
import type { RollupContract } from '@aztec/ethereum';
|
|
3
3
|
import { type TelemetryClient, type Tracer } from '@aztec/telemetry-client';
|
|
4
|
-
import { type
|
|
4
|
+
import { type Hex } from 'viem';
|
|
5
|
+
import type { SequencerState } from './utils.js';
|
|
5
6
|
export declare class SequencerMetrics {
|
|
6
|
-
private coinbase;
|
|
7
7
|
private rollup;
|
|
8
8
|
readonly tracer: Tracer;
|
|
9
9
|
private meter;
|
|
@@ -11,9 +11,6 @@ export declare class SequencerMetrics {
|
|
|
11
11
|
private blockBuildDuration;
|
|
12
12
|
private blockBuildManaPerSecond;
|
|
13
13
|
private stateTransitionBufferDuration;
|
|
14
|
-
private currentBlockNumber;
|
|
15
|
-
private currentBlockSize;
|
|
16
|
-
private blockBuilderInsertions;
|
|
17
14
|
private timeToCollectAttestations;
|
|
18
15
|
private allowanceToCollectAttestations;
|
|
19
16
|
private requiredAttestions;
|
|
@@ -21,23 +18,14 @@ export declare class SequencerMetrics {
|
|
|
21
18
|
private rewards;
|
|
22
19
|
private slots;
|
|
23
20
|
private filledSlots;
|
|
24
|
-
private missedSlots;
|
|
25
21
|
private lastSeenSlot?;
|
|
26
|
-
constructor(client: TelemetryClient,
|
|
27
|
-
setCoinbase(coinbase: EthAddress): void;
|
|
28
|
-
start(): void;
|
|
29
|
-
stop(): void;
|
|
30
|
-
private observe;
|
|
22
|
+
constructor(client: TelemetryClient, rollup: RollupContract, name?: string);
|
|
31
23
|
recordRequiredAttestations(requiredAttestationsCount: number, allowanceMs: number): void;
|
|
32
24
|
recordCollectedAttestations(count: number, durationMs: number): void;
|
|
33
|
-
recordBlockBuilderTreeInsertions(timeUs: number): void;
|
|
34
|
-
recordCancelledBlock(): void;
|
|
35
25
|
recordBuiltBlock(buildDurationMs: number, totalMana: number): void;
|
|
36
26
|
recordFailedBlock(): void;
|
|
37
|
-
recordNewBlock(blockNumber: number, txCount: number): void;
|
|
38
27
|
recordStateTransitionBufferMs(durationMs: number, state: SequencerState): void;
|
|
39
|
-
|
|
40
|
-
incFilledSlot(proposer: string): void
|
|
41
|
-
private setCurrentBlock;
|
|
28
|
+
incOpenSlot(slot: bigint, proposer: string): void;
|
|
29
|
+
incFilledSlot(proposer: string, coinbase: Hex | EthAddress | undefined): Promise<void>;
|
|
42
30
|
}
|
|
43
31
|
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/sequencer/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/sequencer/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAML,KAAK,eAAe,EACpB,KAAK,MAAM,EAGZ,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,KAAK,GAAG,EAAe,MAAM,MAAM,CAAC;AAE7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,qBAAa,gBAAgB;IAwBzB,OAAO,CAAC,MAAM;IAvBhB,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,OAAO,CAAC,KAAK,CAAQ;IAErB,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,kBAAkB,CAAY;IACtC,OAAO,CAAC,uBAAuB,CAAQ;IACvC,OAAO,CAAC,6BAA6B,CAAY;IAGjD,OAAO,CAAC,yBAAyB,CAAQ;IACzC,OAAO,CAAC,8BAA8B,CAAQ;IAC9C,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,mBAAmB,CAAQ;IAEnC,OAAO,CAAC,OAAO,CAAQ;IAEvB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,WAAW,CAAgB;IAEnC,OAAO,CAAC,YAAY,CAAC,CAAS;gBAG5B,MAAM,EAAE,eAAe,EACf,MAAM,EAAE,cAAc,EAC9B,IAAI,SAAc;IAkFb,0BAA0B,CAAC,yBAAyB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IASjF,2BAA2B,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAKpE,gBAAgB,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAQ3D,iBAAiB;IAMjB,6BAA6B,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc;IAMvE,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAapC,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAkB7F"}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { Attributes, Metrics, ValueType } from '@aztec/telemetry-client';
|
|
2
2
|
import { formatUnits } from 'viem';
|
|
3
|
-
import { sequencerStateToNumber } from './utils.js';
|
|
4
3
|
export class SequencerMetrics {
|
|
5
|
-
coinbase;
|
|
6
4
|
rollup;
|
|
7
5
|
tracer;
|
|
8
6
|
meter;
|
|
@@ -10,9 +8,6 @@ export class SequencerMetrics {
|
|
|
10
8
|
blockBuildDuration;
|
|
11
9
|
blockBuildManaPerSecond;
|
|
12
10
|
stateTransitionBufferDuration;
|
|
13
|
-
currentBlockNumber;
|
|
14
|
-
currentBlockSize;
|
|
15
|
-
blockBuilderInsertions;
|
|
16
11
|
// these are gauges because for individual sequencers building a block is not something that happens often enough to warrant a histogram
|
|
17
12
|
timeToCollectAttestations;
|
|
18
13
|
allowanceToCollectAttestations;
|
|
@@ -21,19 +16,9 @@ export class SequencerMetrics {
|
|
|
21
16
|
rewards;
|
|
22
17
|
slots;
|
|
23
18
|
filledSlots;
|
|
24
|
-
missedSlots;
|
|
25
19
|
lastSeenSlot;
|
|
26
|
-
constructor(client,
|
|
27
|
-
this.coinbase = coinbase;
|
|
20
|
+
constructor(client, rollup, name = 'Sequencer'){
|
|
28
21
|
this.rollup = rollup;
|
|
29
|
-
this.observe = async (observer)=>{
|
|
30
|
-
let rewards = 0n;
|
|
31
|
-
rewards = await this.rollup.getSequencerRewards(this.coinbase);
|
|
32
|
-
const fmt = parseFloat(formatUnits(rewards, 18));
|
|
33
|
-
observer.observe(this.rewards, fmt, {
|
|
34
|
-
[Attributes.COINBASE]: this.coinbase.toString()
|
|
35
|
-
});
|
|
36
|
-
};
|
|
37
22
|
this.meter = client.getMeter(name);
|
|
38
23
|
this.tracer = client.getTracer(name);
|
|
39
24
|
this.blockCounter = this.meter.createUpDownCounter(Metrics.SEQUENCER_BLOCK_COUNT);
|
|
@@ -52,37 +37,14 @@ export class SequencerMetrics {
|
|
|
52
37
|
description: 'The time difference between when the sequencer needed to transition to a new state and when it actually did.',
|
|
53
38
|
valueType: ValueType.INT
|
|
54
39
|
});
|
|
55
|
-
const currentState = this.meter.createObservableGauge(Metrics.SEQUENCER_CURRENT_STATE, {
|
|
56
|
-
description: 'Current state of the sequencer'
|
|
57
|
-
});
|
|
58
|
-
currentState.addCallback((observer)=>{
|
|
59
|
-
observer.observe(sequencerStateToNumber(getState()));
|
|
60
|
-
});
|
|
61
|
-
this.currentBlockNumber = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_NUMBER, {
|
|
62
|
-
description: 'Current block number',
|
|
63
|
-
valueType: ValueType.INT
|
|
64
|
-
});
|
|
65
|
-
this.currentBlockSize = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_SIZE, {
|
|
66
|
-
description: 'Current block size',
|
|
67
|
-
valueType: ValueType.INT
|
|
68
|
-
});
|
|
69
|
-
this.blockBuilderInsertions = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_INSERTION_TIME, {
|
|
70
|
-
description: 'Timer for tree insertions performed by the block builder',
|
|
71
|
-
unit: 'us',
|
|
72
|
-
valueType: ValueType.INT
|
|
73
|
-
});
|
|
74
40
|
// Init gauges and counters
|
|
75
|
-
this.setCurrentBlock(0, 0);
|
|
76
|
-
this.blockCounter.add(0, {
|
|
77
|
-
[Attributes.STATUS]: 'cancelled'
|
|
78
|
-
});
|
|
79
41
|
this.blockCounter.add(0, {
|
|
80
42
|
[Attributes.STATUS]: 'failed'
|
|
81
43
|
});
|
|
82
44
|
this.blockCounter.add(0, {
|
|
83
45
|
[Attributes.STATUS]: 'built'
|
|
84
46
|
});
|
|
85
|
-
this.rewards = this.meter.
|
|
47
|
+
this.rewards = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_REWARDS, {
|
|
86
48
|
valueType: ValueType.DOUBLE,
|
|
87
49
|
description: 'The rewards earned'
|
|
88
50
|
});
|
|
@@ -90,14 +52,13 @@ export class SequencerMetrics {
|
|
|
90
52
|
valueType: ValueType.INT,
|
|
91
53
|
description: 'The number of slots this sequencer was selected for'
|
|
92
54
|
});
|
|
93
|
-
|
|
55
|
+
/**
|
|
56
|
+
* NOTE: we do not track missed slots as a separate metric. That would be difficult to determine
|
|
57
|
+
* Instead, use a computed metric, `slots - filledSlots` to get the number of slots a sequencer has missed.
|
|
58
|
+
*/ this.filledSlots = this.meter.createUpDownCounter(Metrics.SEQUENCER_FILLED_SLOT_COUNT, {
|
|
94
59
|
valueType: ValueType.INT,
|
|
95
60
|
description: 'The number of slots this sequencer has filled'
|
|
96
61
|
});
|
|
97
|
-
this.missedSlots = this.meter.createUpDownCounter(Metrics.SEQUENCER_MISSED_SLOT_COUNT, {
|
|
98
|
-
valueType: ValueType.INT,
|
|
99
|
-
description: 'The number of slots this sequencer has missed to fill'
|
|
100
|
-
});
|
|
101
62
|
this.timeToCollectAttestations = this.meter.createGauge(Metrics.SEQUENCER_COLLECT_ATTESTATIONS_DURATION, {
|
|
102
63
|
description: 'The time spent collecting attestations from committee members',
|
|
103
64
|
unit: 'ms',
|
|
@@ -117,20 +78,6 @@ export class SequencerMetrics {
|
|
|
117
78
|
description: 'The minimum number of attestations required to publish a block'
|
|
118
79
|
});
|
|
119
80
|
}
|
|
120
|
-
setCoinbase(coinbase) {
|
|
121
|
-
this.coinbase = coinbase;
|
|
122
|
-
}
|
|
123
|
-
start() {
|
|
124
|
-
this.meter.addBatchObservableCallback(this.observe, [
|
|
125
|
-
this.rewards
|
|
126
|
-
]);
|
|
127
|
-
}
|
|
128
|
-
stop() {
|
|
129
|
-
this.meter.removeBatchObservableCallback(this.observe, [
|
|
130
|
-
this.rewards
|
|
131
|
-
]);
|
|
132
|
-
}
|
|
133
|
-
observe;
|
|
134
81
|
recordRequiredAttestations(requiredAttestationsCount, allowanceMs) {
|
|
135
82
|
this.requiredAttestions.record(requiredAttestationsCount);
|
|
136
83
|
this.allowanceToCollectAttestations.record(Math.ceil(allowanceMs));
|
|
@@ -142,15 +89,6 @@ export class SequencerMetrics {
|
|
|
142
89
|
this.collectedAttestions.record(count);
|
|
143
90
|
this.timeToCollectAttestations.record(Math.ceil(durationMs));
|
|
144
91
|
}
|
|
145
|
-
recordBlockBuilderTreeInsertions(timeUs) {
|
|
146
|
-
this.blockBuilderInsertions.record(Math.ceil(timeUs));
|
|
147
|
-
}
|
|
148
|
-
recordCancelledBlock() {
|
|
149
|
-
this.blockCounter.add(1, {
|
|
150
|
-
[Attributes.STATUS]: 'cancelled'
|
|
151
|
-
});
|
|
152
|
-
this.setCurrentBlock(0, 0);
|
|
153
|
-
}
|
|
154
92
|
recordBuiltBlock(buildDurationMs, totalMana) {
|
|
155
93
|
this.blockCounter.add(1, {
|
|
156
94
|
[Attributes.STATUS]: 'built'
|
|
@@ -162,41 +100,37 @@ export class SequencerMetrics {
|
|
|
162
100
|
this.blockCounter.add(1, {
|
|
163
101
|
[Attributes.STATUS]: 'failed'
|
|
164
102
|
});
|
|
165
|
-
this.setCurrentBlock(0, 0);
|
|
166
|
-
}
|
|
167
|
-
recordNewBlock(blockNumber, txCount) {
|
|
168
|
-
this.setCurrentBlock(blockNumber, txCount);
|
|
169
103
|
}
|
|
170
104
|
recordStateTransitionBufferMs(durationMs, state) {
|
|
171
105
|
this.stateTransitionBufferDuration.record(durationMs, {
|
|
172
106
|
[Attributes.SEQUENCER_STATE]: state
|
|
173
107
|
});
|
|
174
108
|
}
|
|
175
|
-
|
|
109
|
+
incOpenSlot(slot, proposer) {
|
|
176
110
|
// sequencer went through the loop a second time. Noop
|
|
177
111
|
if (slot === this.lastSeenSlot) {
|
|
178
112
|
return;
|
|
179
113
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
if (typeof slot === 'bigint') {
|
|
186
|
-
this.slots.add(1, {
|
|
187
|
-
[Attributes.BLOCK_PROPOSER]: proposer
|
|
188
|
-
});
|
|
189
|
-
}
|
|
114
|
+
this.slots.add(1, {
|
|
115
|
+
[Attributes.BLOCK_PROPOSER]: proposer
|
|
116
|
+
});
|
|
190
117
|
this.lastSeenSlot = slot;
|
|
191
118
|
}
|
|
192
|
-
incFilledSlot(proposer) {
|
|
119
|
+
async incFilledSlot(proposer, coinbase) {
|
|
193
120
|
this.filledSlots.add(1, {
|
|
194
121
|
[Attributes.BLOCK_PROPOSER]: proposer
|
|
195
122
|
});
|
|
196
123
|
this.lastSeenSlot = undefined;
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
124
|
+
if (coinbase) {
|
|
125
|
+
try {
|
|
126
|
+
const rewards = await this.rollup.getSequencerRewards(coinbase);
|
|
127
|
+
const fmt = parseFloat(formatUnits(rewards, 18));
|
|
128
|
+
this.rewards.record(fmt, {
|
|
129
|
+
[Attributes.COINBASE]: coinbase.toString()
|
|
130
|
+
});
|
|
131
|
+
} catch {
|
|
132
|
+
// no-op
|
|
133
|
+
}
|
|
134
|
+
}
|
|
201
135
|
}
|
|
202
136
|
}
|
|
@@ -2,16 +2,17 @@ import type { L2Block } from '@aztec/aztec.js';
|
|
|
2
2
|
import type { EpochCache } from '@aztec/epoch-cache';
|
|
3
3
|
import { type RollupContract } from '@aztec/ethereum';
|
|
4
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
|
+
import { Signature } from '@aztec/foundation/eth-signature';
|
|
5
6
|
import { Fr } from '@aztec/foundation/fields';
|
|
6
7
|
import { type DateProvider } from '@aztec/foundation/timer';
|
|
7
8
|
import type { TypedEventEmitter } from '@aztec/foundation/types';
|
|
8
9
|
import type { P2P } from '@aztec/p2p';
|
|
9
10
|
import type { SlasherClientInterface } from '@aztec/slasher';
|
|
10
|
-
import type
|
|
11
|
+
import { type CommitteeAttestation, CommitteeAttestationsAndSigners, type L2BlockSource, type ValidateBlockResult } from '@aztec/stdlib/block';
|
|
11
12
|
import { type L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
12
13
|
import { type IFullNodeBlockBuilder, type PublicProcessorLimits, type WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
13
14
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
14
|
-
import { Tx
|
|
15
|
+
import { Tx } from '@aztec/stdlib/tx';
|
|
15
16
|
import { type TelemetryClient, type Tracer } from '@aztec/telemetry-client';
|
|
16
17
|
import type { ValidatorClient } from '@aztec/validator-client';
|
|
17
18
|
import type { GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
|
|
@@ -160,7 +161,7 @@ export declare class Sequencer extends Sequencer_base {
|
|
|
160
161
|
* Publishes the L2Block to the rollup contract.
|
|
161
162
|
* @param block - The L2Block to be published.
|
|
162
163
|
*/
|
|
163
|
-
protected enqueuePublishL2Block(block: L2Block,
|
|
164
|
+
protected enqueuePublishL2Block(block: L2Block, attestationsAndSigners: CommitteeAttestationsAndSigners, attestationsAndSignersSignature: Signature, invalidateBlock: InvalidateBlockRequest | undefined, publisher: SequencerPublisher): Promise<void>;
|
|
164
165
|
/**
|
|
165
166
|
* Returns whether all dependencies have caught up.
|
|
166
167
|
* We don't check against the previous block submitted since it may have been reorg'd out.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAwC,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE5F,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAG9C,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"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"}
|