@aztec/sequencer-client 2.0.3-rc.16 → 2.0.3-rc.18
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 +5 -4
- package/dest/publisher/config.d.ts +5 -3
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +13 -5
- 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 +8 -8
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +29 -19
- 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.map +1 -1
- package/dest/sequencer/sequencer.js +5 -10
- package/package.json +27 -27
- package/src/client/sequencer-client.ts +4 -2
- package/src/publisher/config.ts +23 -5
- package/src/publisher/index.ts +1 -1
- package/src/publisher/sequencer-publisher-factory.ts +12 -2
- package/src/publisher/sequencer-publisher.ts +41 -23
- package/src/sequencer/metrics.ts +24 -100
- package/src/sequencer/sequencer.ts +6 -16
|
@@ -28,7 +28,7 @@ import { sumBigint } from '@aztec/foundation/bigint';
|
|
|
28
28
|
import { toHex as toPaddedHex } from '@aztec/foundation/bigint-buffer';
|
|
29
29
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
30
30
|
import type { Fr } from '@aztec/foundation/fields';
|
|
31
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
31
|
+
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
32
32
|
import { bufferToHex } from '@aztec/foundation/string';
|
|
33
33
|
import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
34
34
|
import { EmpireBaseAbi, ErrorsAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
@@ -62,11 +62,6 @@ type L1ProcessArgs = {
|
|
|
62
62
|
attestations?: CommitteeAttestation[];
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
-
export enum SignalType {
|
|
66
|
-
GOVERNANCE,
|
|
67
|
-
SLASHING,
|
|
68
|
-
}
|
|
69
|
-
|
|
70
65
|
export const Actions = [
|
|
71
66
|
'invalidate-by-invalid-attestation',
|
|
72
67
|
'invalidate-by-insufficient-attestations',
|
|
@@ -78,8 +73,11 @@ export const Actions = [
|
|
|
78
73
|
'vote-offenses',
|
|
79
74
|
'execute-slash',
|
|
80
75
|
] as const;
|
|
76
|
+
|
|
81
77
|
export type Action = (typeof Actions)[number];
|
|
82
78
|
|
|
79
|
+
type GovernanceSignalAction = Extract<Action, 'governance-signal' | 'empire-slashing-signal'>;
|
|
80
|
+
|
|
83
81
|
// Sorting for actions such that invalidations go before proposals, and proposals go before votes
|
|
84
82
|
export const compareActions = (a: Action, b: Action) => Actions.indexOf(a) - Actions.indexOf(b);
|
|
85
83
|
|
|
@@ -104,6 +102,7 @@ interface RequestWithExpiry {
|
|
|
104
102
|
}
|
|
105
103
|
|
|
106
104
|
export class SequencerPublisher {
|
|
105
|
+
private enabled: boolean;
|
|
107
106
|
private interrupted = false;
|
|
108
107
|
private metrics: SequencerPublisherMetrics;
|
|
109
108
|
public epochCache: EpochCache;
|
|
@@ -111,12 +110,9 @@ export class SequencerPublisher {
|
|
|
111
110
|
protected governanceLog = createLogger('sequencer:publisher:governance');
|
|
112
111
|
protected slashingLog = createLogger('sequencer:publisher:slashing');
|
|
113
112
|
|
|
114
|
-
|
|
115
|
-
[SignalType.GOVERNANCE]: 0n,
|
|
116
|
-
[SignalType.SLASHING]: 0n,
|
|
117
|
-
};
|
|
113
|
+
protected lastActions: Partial<Record<Action, bigint>> = {};
|
|
118
114
|
|
|
119
|
-
protected log
|
|
115
|
+
protected log: Logger;
|
|
120
116
|
protected ethereumSlotDuration: bigint;
|
|
121
117
|
|
|
122
118
|
private blobSinkClient: BlobSinkClientInterface;
|
|
@@ -152,10 +148,15 @@ export class SequencerPublisher {
|
|
|
152
148
|
epochCache: EpochCache;
|
|
153
149
|
dateProvider: DateProvider;
|
|
154
150
|
metrics: SequencerPublisherMetrics;
|
|
151
|
+
lastActions: Partial<Record<Action, bigint>>;
|
|
152
|
+
log?: Logger;
|
|
155
153
|
},
|
|
156
154
|
) {
|
|
155
|
+
this.enabled = config.publisherEnabled ?? true;
|
|
156
|
+
this.log = deps.log ?? createLogger('sequencer:publisher');
|
|
157
157
|
this.ethereumSlotDuration = BigInt(config.ethereumSlotDuration);
|
|
158
158
|
this.epochCache = deps.epochCache;
|
|
159
|
+
this.lastActions = deps.lastActions;
|
|
159
160
|
|
|
160
161
|
this.blobSinkClient =
|
|
161
162
|
deps.blobSinkClient ?? createBlobSinkClient(config, { logger: createLogger('sequencer:blob-sink:client') });
|
|
@@ -201,6 +202,14 @@ export class SequencerPublisher {
|
|
|
201
202
|
* - undefined if no valid requests are found OR the tx failed to send.
|
|
202
203
|
*/
|
|
203
204
|
public async sendRequests() {
|
|
205
|
+
if (!this.enabled) {
|
|
206
|
+
this.log.warn(`Sending L1 txs is disabled`, {
|
|
207
|
+
requestsDiscarded: this.requests.map(r => r.action),
|
|
208
|
+
});
|
|
209
|
+
this.requests = [];
|
|
210
|
+
return undefined;
|
|
211
|
+
}
|
|
212
|
+
|
|
204
213
|
const requestsToProcess = [...this.requests];
|
|
205
214
|
this.requests = [];
|
|
206
215
|
if (this.interrupted) {
|
|
@@ -528,13 +537,14 @@ export class SequencerPublisher {
|
|
|
528
537
|
private async enqueueCastSignalHelper(
|
|
529
538
|
slotNumber: bigint,
|
|
530
539
|
timestamp: bigint,
|
|
531
|
-
signalType:
|
|
540
|
+
signalType: GovernanceSignalAction,
|
|
532
541
|
payload: EthAddress,
|
|
533
542
|
base: IEmpireBase,
|
|
534
543
|
signerAddress: EthAddress,
|
|
535
544
|
signer: (msg: TypedDataDefinition) => Promise<`0x${string}`>,
|
|
536
545
|
): Promise<boolean> {
|
|
537
|
-
if (this.
|
|
546
|
+
if (this.lastActions[signalType] && this.lastActions[signalType] === slotNumber) {
|
|
547
|
+
this.log.debug(`Skipping duplicate vote cast signal ${signalType} for slot ${slotNumber}`);
|
|
538
548
|
return false;
|
|
539
549
|
}
|
|
540
550
|
if (payload.equals(EthAddress.ZERO)) {
|
|
@@ -551,10 +561,9 @@ export class SequencerPublisher {
|
|
|
551
561
|
return false;
|
|
552
562
|
}
|
|
553
563
|
|
|
554
|
-
const cachedLastVote = this.
|
|
555
|
-
this.
|
|
556
|
-
|
|
557
|
-
const action = signalType === SignalType.GOVERNANCE ? 'governance-signal' : 'empire-slashing-signal';
|
|
564
|
+
const cachedLastVote = this.lastActions[signalType];
|
|
565
|
+
this.lastActions[signalType] = slotNumber;
|
|
566
|
+
const action = signalType;
|
|
558
567
|
|
|
559
568
|
const request = await base.createSignalRequestWithSignature(
|
|
560
569
|
payload.toString(),
|
|
@@ -597,7 +606,7 @@ export class SequencerPublisher {
|
|
|
597
606
|
`Signaling in [${action}] for ${payload} at slot ${slotNumber} in round ${round} failed`,
|
|
598
607
|
logData,
|
|
599
608
|
);
|
|
600
|
-
this.
|
|
609
|
+
this.lastActions[signalType] = cachedLastVote;
|
|
601
610
|
return false;
|
|
602
611
|
} else {
|
|
603
612
|
this.log.info(
|
|
@@ -627,7 +636,7 @@ export class SequencerPublisher {
|
|
|
627
636
|
return this.enqueueCastSignalHelper(
|
|
628
637
|
slotNumber,
|
|
629
638
|
timestamp,
|
|
630
|
-
|
|
639
|
+
'governance-signal',
|
|
631
640
|
governancePayload,
|
|
632
641
|
this.govProposerContract,
|
|
633
642
|
signerAddress,
|
|
@@ -661,7 +670,7 @@ export class SequencerPublisher {
|
|
|
661
670
|
await this.enqueueCastSignalHelper(
|
|
662
671
|
slotNumber,
|
|
663
672
|
timestamp,
|
|
664
|
-
|
|
673
|
+
'empire-slashing-signal',
|
|
665
674
|
action.payload,
|
|
666
675
|
this.slashingProposerContract,
|
|
667
676
|
signerAddress,
|
|
@@ -842,16 +851,24 @@ export class SequencerPublisher {
|
|
|
842
851
|
}
|
|
843
852
|
|
|
844
853
|
private async simulateAndEnqueueRequest(
|
|
845
|
-
action:
|
|
854
|
+
action: Action,
|
|
846
855
|
request: L1TxRequest,
|
|
847
856
|
checkSuccess: (receipt: TransactionReceipt) => boolean | undefined,
|
|
848
857
|
slotNumber: bigint,
|
|
849
858
|
timestamp: bigint,
|
|
850
859
|
) {
|
|
851
860
|
const logData = { slotNumber, timestamp, gasLimit: undefined as bigint | undefined };
|
|
852
|
-
|
|
861
|
+
if (this.lastActions[action] && this.lastActions[action] === slotNumber) {
|
|
862
|
+
this.log.debug(`Skipping duplicate action ${action} for slot ${slotNumber}`);
|
|
863
|
+
return false;
|
|
864
|
+
}
|
|
853
865
|
|
|
854
|
-
this.
|
|
866
|
+
const cachedLastActionSlot = this.lastActions[action];
|
|
867
|
+
this.lastActions[action] = slotNumber;
|
|
868
|
+
|
|
869
|
+
this.log.debug(`Simulating ${action} for slot ${slotNumber}`, logData);
|
|
870
|
+
|
|
871
|
+
let gasUsed: bigint;
|
|
855
872
|
try {
|
|
856
873
|
({ gasUsed } = await this.l1TxUtils.simulate(request, { time: timestamp }, [], ErrorsAbi)); // TODO(palla/slash): Check the timestamp logic
|
|
857
874
|
this.log.verbose(`Simulation for ${action} succeeded`, { ...logData, request, gasUsed });
|
|
@@ -875,6 +892,7 @@ export class SequencerPublisher {
|
|
|
875
892
|
const success = result && result.receipt && result.receipt.status === 'success' && checkSuccess(result.receipt);
|
|
876
893
|
if (!success) {
|
|
877
894
|
this.log.warn(`Action ${action} at ${slotNumber} failed`, { ...result, ...logData });
|
|
895
|
+
this.lastActions[action] = cachedLastActionSlot;
|
|
878
896
|
} else {
|
|
879
897
|
this.log.info(`Action ${action} at ${slotNumber} succeeded`, { ...result, ...logData });
|
|
880
898
|
}
|
package/src/sequencer/metrics.ts
CHANGED
|
@@ -2,21 +2,19 @@ import type { EthAddress } from '@aztec/aztec.js';
|
|
|
2
2
|
import type { RollupContract } from '@aztec/ethereum';
|
|
3
3
|
import {
|
|
4
4
|
Attributes,
|
|
5
|
-
type BatchObservableResult,
|
|
6
5
|
type Gauge,
|
|
7
6
|
type Histogram,
|
|
8
7
|
type Meter,
|
|
9
8
|
Metrics,
|
|
10
|
-
type ObservableGauge,
|
|
11
9
|
type TelemetryClient,
|
|
12
10
|
type Tracer,
|
|
13
11
|
type UpDownCounter,
|
|
14
12
|
ValueType,
|
|
15
13
|
} from '@aztec/telemetry-client';
|
|
16
14
|
|
|
17
|
-
import { formatUnits } from 'viem';
|
|
15
|
+
import { type Hex, formatUnits } from 'viem';
|
|
18
16
|
|
|
19
|
-
import {
|
|
17
|
+
import type { SequencerState } from './utils.js';
|
|
20
18
|
|
|
21
19
|
export class SequencerMetrics {
|
|
22
20
|
public readonly tracer: Tracer;
|
|
@@ -26,9 +24,6 @@ export class SequencerMetrics {
|
|
|
26
24
|
private blockBuildDuration: Histogram;
|
|
27
25
|
private blockBuildManaPerSecond: Gauge;
|
|
28
26
|
private stateTransitionBufferDuration: Histogram;
|
|
29
|
-
private currentBlockNumber: Gauge;
|
|
30
|
-
private currentBlockSize: Gauge;
|
|
31
|
-
private blockBuilderInsertions: Histogram;
|
|
32
27
|
|
|
33
28
|
// these are gauges because for individual sequencers building a block is not something that happens often enough to warrant a histogram
|
|
34
29
|
private timeToCollectAttestations: Gauge;
|
|
@@ -36,18 +31,15 @@ export class SequencerMetrics {
|
|
|
36
31
|
private requiredAttestions: Gauge;
|
|
37
32
|
private collectedAttestions: Gauge;
|
|
38
33
|
|
|
39
|
-
private rewards:
|
|
34
|
+
private rewards: Gauge;
|
|
40
35
|
|
|
41
36
|
private slots: UpDownCounter;
|
|
42
37
|
private filledSlots: UpDownCounter;
|
|
43
|
-
private missedSlots: UpDownCounter;
|
|
44
38
|
|
|
45
39
|
private lastSeenSlot?: bigint;
|
|
46
40
|
|
|
47
41
|
constructor(
|
|
48
42
|
client: TelemetryClient,
|
|
49
|
-
getState: SequencerStateCallback,
|
|
50
|
-
private coinbase: EthAddress,
|
|
51
43
|
private rollup: RollupContract,
|
|
52
44
|
name = 'Sequencer',
|
|
53
45
|
) {
|
|
@@ -78,35 +70,7 @@ export class SequencerMetrics {
|
|
|
78
70
|
},
|
|
79
71
|
);
|
|
80
72
|
|
|
81
|
-
const currentState = this.meter.createObservableGauge(Metrics.SEQUENCER_CURRENT_STATE, {
|
|
82
|
-
description: 'Current state of the sequencer',
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
currentState.addCallback(observer => {
|
|
86
|
-
observer.observe(sequencerStateToNumber(getState()));
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
this.currentBlockNumber = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_NUMBER, {
|
|
90
|
-
description: 'Current block number',
|
|
91
|
-
valueType: ValueType.INT,
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
this.currentBlockSize = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_SIZE, {
|
|
95
|
-
description: 'Current block size',
|
|
96
|
-
valueType: ValueType.INT,
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
this.blockBuilderInsertions = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_INSERTION_TIME, {
|
|
100
|
-
description: 'Timer for tree insertions performed by the block builder',
|
|
101
|
-
unit: 'us',
|
|
102
|
-
valueType: ValueType.INT,
|
|
103
|
-
});
|
|
104
|
-
|
|
105
73
|
// Init gauges and counters
|
|
106
|
-
this.setCurrentBlock(0, 0);
|
|
107
|
-
this.blockCounter.add(0, {
|
|
108
|
-
[Attributes.STATUS]: 'cancelled',
|
|
109
|
-
});
|
|
110
74
|
this.blockCounter.add(0, {
|
|
111
75
|
[Attributes.STATUS]: 'failed',
|
|
112
76
|
});
|
|
@@ -114,7 +78,7 @@ export class SequencerMetrics {
|
|
|
114
78
|
[Attributes.STATUS]: 'built',
|
|
115
79
|
});
|
|
116
80
|
|
|
117
|
-
this.rewards = this.meter.
|
|
81
|
+
this.rewards = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_REWARDS, {
|
|
118
82
|
valueType: ValueType.DOUBLE,
|
|
119
83
|
description: 'The rewards earned',
|
|
120
84
|
});
|
|
@@ -124,16 +88,15 @@ export class SequencerMetrics {
|
|
|
124
88
|
description: 'The number of slots this sequencer was selected for',
|
|
125
89
|
});
|
|
126
90
|
|
|
91
|
+
/**
|
|
92
|
+
* NOTE: we do not track missed slots as a separate metric. That would be difficult to determine
|
|
93
|
+
* Instead, use a computed metric, `slots - filledSlots` to get the number of slots a sequencer has missed.
|
|
94
|
+
*/
|
|
127
95
|
this.filledSlots = this.meter.createUpDownCounter(Metrics.SEQUENCER_FILLED_SLOT_COUNT, {
|
|
128
96
|
valueType: ValueType.INT,
|
|
129
97
|
description: 'The number of slots this sequencer has filled',
|
|
130
98
|
});
|
|
131
99
|
|
|
132
|
-
this.missedSlots = this.meter.createUpDownCounter(Metrics.SEQUENCER_MISSED_SLOT_COUNT, {
|
|
133
|
-
valueType: ValueType.INT,
|
|
134
|
-
description: 'The number of slots this sequencer has missed to fill',
|
|
135
|
-
});
|
|
136
|
-
|
|
137
100
|
this.timeToCollectAttestations = this.meter.createGauge(Metrics.SEQUENCER_COLLECT_ATTESTATIONS_DURATION, {
|
|
138
101
|
description: 'The time spent collecting attestations from committee members',
|
|
139
102
|
unit: 'ms',
|
|
@@ -160,28 +123,6 @@ export class SequencerMetrics {
|
|
|
160
123
|
});
|
|
161
124
|
}
|
|
162
125
|
|
|
163
|
-
public setCoinbase(coinbase: EthAddress) {
|
|
164
|
-
this.coinbase = coinbase;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
public start() {
|
|
168
|
-
this.meter.addBatchObservableCallback(this.observe, [this.rewards]);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
public stop() {
|
|
172
|
-
this.meter.removeBatchObservableCallback(this.observe, [this.rewards]);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
private observe = async (observer: BatchObservableResult): Promise<void> => {
|
|
176
|
-
let rewards = 0n;
|
|
177
|
-
rewards = await this.rollup.getSequencerRewards(this.coinbase);
|
|
178
|
-
|
|
179
|
-
const fmt = parseFloat(formatUnits(rewards, 18));
|
|
180
|
-
observer.observe(this.rewards, fmt, {
|
|
181
|
-
[Attributes.COINBASE]: this.coinbase.toString(),
|
|
182
|
-
});
|
|
183
|
-
};
|
|
184
|
-
|
|
185
126
|
public recordRequiredAttestations(requiredAttestationsCount: number, allowanceMs: number) {
|
|
186
127
|
this.requiredAttestions.record(requiredAttestationsCount);
|
|
187
128
|
this.allowanceToCollectAttestations.record(Math.ceil(allowanceMs));
|
|
@@ -196,17 +137,6 @@ export class SequencerMetrics {
|
|
|
196
137
|
this.timeToCollectAttestations.record(Math.ceil(durationMs));
|
|
197
138
|
}
|
|
198
139
|
|
|
199
|
-
recordBlockBuilderTreeInsertions(timeUs: number) {
|
|
200
|
-
this.blockBuilderInsertions.record(Math.ceil(timeUs));
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
recordCancelledBlock() {
|
|
204
|
-
this.blockCounter.add(1, {
|
|
205
|
-
[Attributes.STATUS]: 'cancelled',
|
|
206
|
-
});
|
|
207
|
-
this.setCurrentBlock(0, 0);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
140
|
recordBuiltBlock(buildDurationMs: number, totalMana: number) {
|
|
211
141
|
this.blockCounter.add(1, {
|
|
212
142
|
[Attributes.STATUS]: 'built',
|
|
@@ -219,11 +149,6 @@ export class SequencerMetrics {
|
|
|
219
149
|
this.blockCounter.add(1, {
|
|
220
150
|
[Attributes.STATUS]: 'failed',
|
|
221
151
|
});
|
|
222
|
-
this.setCurrentBlock(0, 0);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
recordNewBlock(blockNumber: number, txCount: number) {
|
|
226
|
-
this.setCurrentBlock(blockNumber, txCount);
|
|
227
152
|
}
|
|
228
153
|
|
|
229
154
|
recordStateTransitionBufferMs(durationMs: number, state: SequencerState) {
|
|
@@ -232,36 +157,35 @@ export class SequencerMetrics {
|
|
|
232
157
|
});
|
|
233
158
|
}
|
|
234
159
|
|
|
235
|
-
|
|
160
|
+
incOpenSlot(slot: bigint, proposer: string) {
|
|
236
161
|
// sequencer went through the loop a second time. Noop
|
|
237
162
|
if (slot === this.lastSeenSlot) {
|
|
238
163
|
return;
|
|
239
164
|
}
|
|
240
165
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
if (typeof slot === 'bigint') {
|
|
248
|
-
this.slots.add(1, {
|
|
249
|
-
[Attributes.BLOCK_PROPOSER]: proposer,
|
|
250
|
-
});
|
|
251
|
-
}
|
|
166
|
+
this.slots.add(1, {
|
|
167
|
+
[Attributes.BLOCK_PROPOSER]: proposer,
|
|
168
|
+
});
|
|
252
169
|
|
|
253
170
|
this.lastSeenSlot = slot;
|
|
254
171
|
}
|
|
255
172
|
|
|
256
|
-
incFilledSlot(proposer: string) {
|
|
173
|
+
async incFilledSlot(proposer: string, coinbase: Hex | EthAddress | undefined): Promise<void> {
|
|
257
174
|
this.filledSlots.add(1, {
|
|
258
175
|
[Attributes.BLOCK_PROPOSER]: proposer,
|
|
259
176
|
});
|
|
260
177
|
this.lastSeenSlot = undefined;
|
|
261
|
-
}
|
|
262
178
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
179
|
+
if (coinbase) {
|
|
180
|
+
try {
|
|
181
|
+
const rewards = await this.rollup.getSequencerRewards(coinbase);
|
|
182
|
+
const fmt = parseFloat(formatUnits(rewards, 18));
|
|
183
|
+
this.rewards.record(fmt, {
|
|
184
|
+
[Attributes.COINBASE]: coinbase.toString(),
|
|
185
|
+
});
|
|
186
|
+
} catch {
|
|
187
|
+
// no-op
|
|
188
|
+
}
|
|
189
|
+
}
|
|
266
190
|
}
|
|
267
191
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { L2Block } from '@aztec/aztec.js';
|
|
2
|
-
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
2
|
+
import { BLOBS_PER_BLOCK, FIELDS_PER_BLOB, INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
3
3
|
import type { EpochCache } from '@aztec/epoch-cache';
|
|
4
4
|
import { FormattedViemError, NoCommitteeError, type RollupContract } from '@aztec/ethereum';
|
|
5
5
|
import { omit, pick } from '@aztec/foundation/collection';
|
|
@@ -127,15 +127,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
127
127
|
) {
|
|
128
128
|
super();
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
const validatorAddresses = this.validatorClient?.getValidatorAddresses() ?? [];
|
|
132
|
-
const coinbase =
|
|
133
|
-
validatorAddresses.length === 0
|
|
134
|
-
? EthAddress.ZERO
|
|
135
|
-
: (this.validatorClient?.getCoinbaseForAttestor(validatorAddresses[0]) ?? EthAddress.ZERO);
|
|
136
|
-
|
|
137
|
-
this.metrics = new SequencerMetrics(telemetry, () => this.state, coinbase, this.rollupContract, 'Sequencer');
|
|
138
|
-
|
|
130
|
+
this.metrics = new SequencerMetrics(telemetry, this.rollupContract, 'Sequencer');
|
|
139
131
|
// Initialize config
|
|
140
132
|
this.updateConfig(this.config);
|
|
141
133
|
}
|
|
@@ -220,7 +212,6 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
220
212
|
* Starts the sequencer and moves to IDLE state.
|
|
221
213
|
*/
|
|
222
214
|
public start() {
|
|
223
|
-
this.metrics.start();
|
|
224
215
|
this.runningPromise = new RunningPromise(this.work.bind(this), this.log, this.pollingIntervalMs);
|
|
225
216
|
this.setState(SequencerState.IDLE, undefined, { force: true });
|
|
226
217
|
this.runningPromise.start();
|
|
@@ -232,7 +223,6 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
232
223
|
*/
|
|
233
224
|
public async stop(): Promise<void> {
|
|
234
225
|
this.log.info(`Stopping sequencer`);
|
|
235
|
-
this.metrics.stop();
|
|
236
226
|
this.publisher?.interrupt();
|
|
237
227
|
await this.validatorClient?.stop();
|
|
238
228
|
await this.runningPromise?.stop();
|
|
@@ -361,8 +351,6 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
361
351
|
const coinbase = this.validatorClient!.getCoinbaseForAttestor(attestorAddress);
|
|
362
352
|
const feeRecipient = this.validatorClient!.getFeeRecipientForAttestor(attestorAddress);
|
|
363
353
|
|
|
364
|
-
this.metrics.setCoinbase(coinbase);
|
|
365
|
-
|
|
366
354
|
// Prepare invalidation request if the pending chain is invalid (returns undefined if no need)
|
|
367
355
|
const invalidateBlock = await publisher.simulateInvalidateBlock(syncedTo.pendingChainValidationStatus);
|
|
368
356
|
const canProposeCheck = await publisher.canProposeAtNextEthBlock(
|
|
@@ -435,6 +423,8 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
435
423
|
}
|
|
436
424
|
|
|
437
425
|
this.setState(SequencerState.INITIALIZING_PROPOSAL, slot);
|
|
426
|
+
|
|
427
|
+
this.metrics.incOpenSlot(slot, proposerAddressInNextSlot.toString());
|
|
438
428
|
this.log.verbose(`Preparing proposal for block ${newBlockNumber} at slot ${slot}`, {
|
|
439
429
|
proposer: proposerInNextSlot?.toString(),
|
|
440
430
|
coinbase,
|
|
@@ -494,7 +484,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
494
484
|
if (proposedBlock) {
|
|
495
485
|
this.lastBlockPublished = block;
|
|
496
486
|
this.emit('block-published', { blockNumber: newBlockNumber, slot: Number(slot) });
|
|
497
|
-
this.metrics.incFilledSlot(publisher.getSenderAddress().toString());
|
|
487
|
+
await this.metrics.incFilledSlot(publisher.getSenderAddress().toString(), coinbase);
|
|
498
488
|
} else if (block) {
|
|
499
489
|
this.emit('block-publish-failed', l1Response ?? {});
|
|
500
490
|
}
|
|
@@ -584,6 +574,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
584
574
|
maxTransactions: this.maxTxsPerBlock,
|
|
585
575
|
maxBlockSize: this.maxBlockSizeInBytes,
|
|
586
576
|
maxBlockGas: this.maxBlockGas,
|
|
577
|
+
maxBlobFields: BLOBS_PER_BLOCK * FIELDS_PER_BLOB,
|
|
587
578
|
deadline,
|
|
588
579
|
};
|
|
589
580
|
}
|
|
@@ -616,7 +607,6 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
616
607
|
const slot = proposalHeader.slotNumber.toBigInt();
|
|
617
608
|
const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(blockNumber);
|
|
618
609
|
|
|
619
|
-
// this.metrics.recordNewBlock(blockNumber, validTxs.length);
|
|
620
610
|
const workTimer = new Timer();
|
|
621
611
|
this.setState(SequencerState.CREATING_BLOCK, slot);
|
|
622
612
|
|