@aztec/sequencer-client 0.0.1-commit.e6bd8901 → 0.0.1-commit.ec7ac5448
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 +17 -7
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +63 -30
- package/dest/config.d.ts +26 -7
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +47 -33
- package/dest/global_variable_builder/global_builder.d.ts +15 -10
- package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
- package/dest/global_variable_builder/global_builder.js +26 -26
- package/dest/global_variable_builder/index.d.ts +2 -2
- package/dest/global_variable_builder/index.d.ts.map +1 -1
- package/dest/publisher/config.d.ts +47 -17
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +121 -42
- package/dest/publisher/index.d.ts +2 -1
- package/dest/publisher/index.d.ts.map +1 -1
- package/dest/publisher/l1_tx_failed_store/factory.d.ts +11 -0
- package/dest/publisher/l1_tx_failed_store/factory.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/factory.js +22 -0
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts +59 -0
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.js +1 -0
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts +15 -0
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.js +34 -0
- package/dest/publisher/l1_tx_failed_store/index.d.ts +4 -0
- package/dest/publisher/l1_tx_failed_store/index.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/index.js +2 -0
- package/dest/publisher/sequencer-publisher-factory.d.ts +11 -5
- package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-factory.js +27 -3
- 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 +12 -4
- package/dest/publisher/sequencer-publisher.d.ts +75 -49
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +470 -156
- package/dest/sequencer/chain_state_overrides.d.ts +25 -0
- package/dest/sequencer/chain_state_overrides.d.ts.map +1 -0
- package/dest/sequencer/chain_state_overrides.js +39 -0
- package/dest/sequencer/checkpoint_proposal_job.d.ts +51 -13
- package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_proposal_job.js +414 -239
- package/dest/sequencer/checkpoint_voter.d.ts +1 -2
- package/dest/sequencer/checkpoint_voter.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_voter.js +2 -5
- package/dest/sequencer/events.d.ts +2 -1
- package/dest/sequencer/events.d.ts.map +1 -1
- package/dest/sequencer/metrics.d.ts +25 -6
- package/dest/sequencer/metrics.d.ts.map +1 -1
- package/dest/sequencer/metrics.js +134 -31
- package/dest/sequencer/sequencer.d.ts +44 -17
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +157 -94
- package/dest/sequencer/timetable.d.ts +17 -6
- package/dest/sequencer/timetable.d.ts.map +1 -1
- package/dest/sequencer/timetable.js +51 -46
- package/dest/sequencer/types.d.ts +2 -2
- package/dest/sequencer/types.d.ts.map +1 -1
- package/dest/test/index.d.ts +3 -5
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/mock_checkpoint_builder.d.ts +14 -11
- package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
- package/dest/test/mock_checkpoint_builder.js +63 -40
- package/dest/test/utils.d.ts +3 -3
- package/dest/test/utils.d.ts.map +1 -1
- package/dest/test/utils.js +5 -4
- package/package.json +27 -28
- package/src/client/sequencer-client.ts +81 -30
- package/src/config.ts +65 -43
- package/src/global_variable_builder/global_builder.ts +31 -28
- package/src/global_variable_builder/index.ts +1 -1
- package/src/publisher/config.ts +153 -43
- package/src/publisher/index.ts +3 -0
- package/src/publisher/l1_tx_failed_store/factory.ts +32 -0
- package/src/publisher/l1_tx_failed_store/failed_tx_store.ts +55 -0
- package/src/publisher/l1_tx_failed_store/file_store_failed_tx_store.ts +46 -0
- package/src/publisher/l1_tx_failed_store/index.ts +3 -0
- package/src/publisher/sequencer-publisher-factory.ts +38 -9
- package/src/publisher/sequencer-publisher-metrics.ts +7 -3
- package/src/publisher/sequencer-publisher.ts +531 -214
- package/src/sequencer/README.md +83 -13
- package/src/sequencer/chain_state_overrides.ts +87 -0
- package/src/sequencer/checkpoint_proposal_job.ts +547 -274
- package/src/sequencer/checkpoint_voter.ts +1 -12
- package/src/sequencer/events.ts +1 -1
- package/src/sequencer/metrics.ts +153 -33
- package/src/sequencer/sequencer.ts +228 -107
- package/src/sequencer/timetable.ts +70 -57
- package/src/sequencer/types.ts +1 -1
- package/src/test/index.ts +2 -4
- package/src/test/mock_checkpoint_builder.ts +84 -56
- package/src/test/utils.ts +5 -2
|
@@ -2,7 +2,6 @@ import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
|
2
2
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
3
|
import type { Logger } from '@aztec/foundation/log';
|
|
4
4
|
import type { SlasherClientInterface } from '@aztec/slasher';
|
|
5
|
-
import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
6
5
|
import type { ResolvedSequencerConfig } from '@aztec/stdlib/interfaces/server';
|
|
7
6
|
import type { ValidatorClient } from '@aztec/validator-client';
|
|
8
7
|
import { DutyAlreadySignedError } from '@aztec/validator-ha-signer/errors';
|
|
@@ -18,7 +17,6 @@ import type { SequencerRollupConstants } from './types.js';
|
|
|
18
17
|
* Handles governance and slashing voting for a given slot.
|
|
19
18
|
*/
|
|
20
19
|
export class CheckpointVoter {
|
|
21
|
-
private slotTimestamp: bigint;
|
|
22
20
|
private governanceSigner: (msg: TypedDataDefinition) => Promise<`0x${string}`>;
|
|
23
21
|
private slashingSigner: (msg: TypedDataDefinition) => Promise<`0x${string}`>;
|
|
24
22
|
|
|
@@ -33,8 +31,6 @@ export class CheckpointVoter {
|
|
|
33
31
|
private readonly metrics: SequencerMetrics,
|
|
34
32
|
private readonly log: Logger,
|
|
35
33
|
) {
|
|
36
|
-
this.slotTimestamp = getTimestampForSlot(this.slot, this.l1Constants);
|
|
37
|
-
|
|
38
34
|
// Create separate signers with appropriate duty contexts for governance and slashing votes
|
|
39
35
|
// These use HA protection to ensure only one node signs per slot/duty
|
|
40
36
|
const governanceContext: SigningContext = { slot: this.slot, dutyType: DutyType.GOVERNANCE_VOTE };
|
|
@@ -77,7 +73,6 @@ export class CheckpointVoter {
|
|
|
77
73
|
return await this.publisher.enqueueGovernanceCastSignal(
|
|
78
74
|
governanceProposerPayload,
|
|
79
75
|
this.slot,
|
|
80
|
-
this.slotTimestamp,
|
|
81
76
|
this.attestorAddress,
|
|
82
77
|
this.governanceSigner,
|
|
83
78
|
);
|
|
@@ -108,13 +103,7 @@ export class CheckpointVoter {
|
|
|
108
103
|
|
|
109
104
|
this.metrics.recordSlashingAttempt(actions.length);
|
|
110
105
|
|
|
111
|
-
return await this.publisher.enqueueSlashingActions(
|
|
112
|
-
actions,
|
|
113
|
-
this.slot,
|
|
114
|
-
this.slotTimestamp,
|
|
115
|
-
this.attestorAddress,
|
|
116
|
-
this.slashingSigner,
|
|
117
|
-
);
|
|
106
|
+
return await this.publisher.enqueueSlashingActions(actions, this.slot, this.attestorAddress, this.slashingSigner);
|
|
118
107
|
} catch (err) {
|
|
119
108
|
if (err instanceof DutyAlreadySignedError) {
|
|
120
109
|
this.log.info(`Slashing vote already signed by another node`, {
|
package/src/sequencer/events.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type SequencerEvents = {
|
|
|
13
13
|
['proposer-rollup-check-failed']: (args: { reason: string; slot: SlotNumber }) => void;
|
|
14
14
|
['block-tx-count-check-failed']: (args: { minTxs: number; availableTxs: number; slot: SlotNumber }) => void;
|
|
15
15
|
['block-build-failed']: (args: { reason: string; slot: SlotNumber }) => void;
|
|
16
|
-
['block-proposed']: (args: { blockNumber: BlockNumber; slot: SlotNumber }) => void;
|
|
16
|
+
['block-proposed']: (args: { blockNumber: BlockNumber; slot: SlotNumber; buildSlot: SlotNumber }) => void;
|
|
17
17
|
['checkpoint-empty']: (args: { slot: SlotNumber }) => void;
|
|
18
18
|
['checkpoint-publish-failed']: (args: {
|
|
19
19
|
slot: SlotNumber;
|
package/src/sequencer/metrics.ts
CHANGED
|
@@ -11,13 +11,13 @@ import {
|
|
|
11
11
|
type TelemetryClient,
|
|
12
12
|
type Tracer,
|
|
13
13
|
type UpDownCounter,
|
|
14
|
+
createUpDownCounterWithDefault,
|
|
14
15
|
} from '@aztec/telemetry-client';
|
|
15
16
|
|
|
16
17
|
import { type Hex, formatUnits } from 'viem';
|
|
17
18
|
|
|
18
19
|
import type { SequencerState } from './utils.js';
|
|
19
20
|
|
|
20
|
-
// TODO(palla/mbps): Review all metrics and add any missing ones per checkpoint
|
|
21
21
|
export class SequencerMetrics {
|
|
22
22
|
public readonly tracer: Tracer;
|
|
23
23
|
private meter: Meter;
|
|
@@ -39,17 +39,28 @@ export class SequencerMetrics {
|
|
|
39
39
|
private filledSlots: UpDownCounter;
|
|
40
40
|
|
|
41
41
|
private blockProposalFailed: UpDownCounter;
|
|
42
|
-
private
|
|
43
|
-
private
|
|
42
|
+
private checkpointProposalSuccess: UpDownCounter;
|
|
43
|
+
private checkpointPrecheckFailed: UpDownCounter;
|
|
44
|
+
private checkpointProposalFailed: UpDownCounter;
|
|
44
45
|
private checkpointSuccess: UpDownCounter;
|
|
45
46
|
private slashingAttempts: UpDownCounter;
|
|
46
47
|
private checkpointAttestationDelay: Histogram;
|
|
48
|
+
private checkpointBuildDuration: Histogram;
|
|
49
|
+
private checkpointBlockCount: Gauge;
|
|
50
|
+
private checkpointTxCount: Gauge;
|
|
51
|
+
private checkpointTotalMana: Gauge;
|
|
52
|
+
private pipelineDepth: Gauge;
|
|
53
|
+
private pipelineDiscards: UpDownCounter;
|
|
47
54
|
|
|
48
55
|
// Fisherman fee analysis metrics
|
|
49
56
|
private fishermanWouldBeIncluded: UpDownCounter;
|
|
50
57
|
private fishermanTimeBeforeBlock: Histogram;
|
|
51
58
|
private fishermanPendingBlobTxCount: Histogram;
|
|
52
59
|
private fishermanIncludedBlobTxCount: Histogram;
|
|
60
|
+
private fishermanPendingBlobCount: Histogram;
|
|
61
|
+
private fishermanIncludedBlobCount: Histogram;
|
|
62
|
+
private fishermanBlockBlobsFull: UpDownCounter;
|
|
63
|
+
private fishermanMaxBlobCapacity: Histogram;
|
|
53
64
|
private fishermanCalculatedPriorityFee: Histogram;
|
|
54
65
|
private fishermanPriorityFeeDelta: Histogram;
|
|
55
66
|
private fishermanEstimatedCost: Histogram;
|
|
@@ -57,6 +68,10 @@ export class SequencerMetrics {
|
|
|
57
68
|
private fishermanMinedBlobTxPriorityFee: Histogram;
|
|
58
69
|
private fishermanMinedBlobTxTotalCost: Histogram;
|
|
59
70
|
|
|
71
|
+
private blockInterBlockTime: Histogram;
|
|
72
|
+
private lastBlockBuiltTimestamp?: number;
|
|
73
|
+
private lastBlockBuiltSlot?: SlotNumber;
|
|
74
|
+
|
|
60
75
|
private lastSeenSlot?: SlotNumber;
|
|
61
76
|
|
|
62
77
|
constructor(
|
|
@@ -67,33 +82,29 @@ export class SequencerMetrics {
|
|
|
67
82
|
this.meter = client.getMeter(name);
|
|
68
83
|
this.tracer = client.getTracer(name);
|
|
69
84
|
|
|
70
|
-
this.blockCounter = this.meter
|
|
85
|
+
this.blockCounter = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_BLOCK_COUNT, {
|
|
86
|
+
[Attributes.STATUS]: ['failed', 'built'],
|
|
87
|
+
});
|
|
71
88
|
|
|
72
89
|
this.blockBuildDuration = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_DURATION);
|
|
73
90
|
|
|
74
91
|
this.blockBuildManaPerSecond = this.meter.createGauge(Metrics.SEQUENCER_BLOCK_BUILD_MANA_PER_SECOND);
|
|
75
92
|
|
|
93
|
+
this.blockInterBlockTime = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_INTER_BLOCK_TIME);
|
|
94
|
+
|
|
76
95
|
this.stateTransitionBufferDuration = this.meter.createHistogram(Metrics.SEQUENCER_STATE_TRANSITION_BUFFER_DURATION);
|
|
77
96
|
|
|
78
97
|
this.checkpointAttestationDelay = this.meter.createHistogram(Metrics.SEQUENCER_CHECKPOINT_ATTESTATION_DELAY);
|
|
79
98
|
|
|
80
|
-
|
|
81
|
-
this.blockCounter.add(0, {
|
|
82
|
-
[Attributes.STATUS]: 'failed',
|
|
83
|
-
});
|
|
84
|
-
this.blockCounter.add(0, {
|
|
85
|
-
[Attributes.STATUS]: 'built',
|
|
86
|
-
});
|
|
99
|
+
this.rewards = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_SLOT_REWARDS);
|
|
87
100
|
|
|
88
|
-
this.
|
|
89
|
-
|
|
90
|
-
this.slots = this.meter.createUpDownCounter(Metrics.SEQUENCER_SLOT_COUNT);
|
|
101
|
+
this.slots = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_SLOT_COUNT);
|
|
91
102
|
|
|
92
103
|
/**
|
|
93
104
|
* NOTE: we do not track missed slots as a separate metric. That would be difficult to determine
|
|
94
105
|
* Instead, use a computed metric, `slots - filledSlots` to get the number of slots a sequencer has missed.
|
|
95
106
|
*/
|
|
96
|
-
this.filledSlots = this.meter
|
|
107
|
+
this.filledSlots = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_FILLED_SLOT_COUNT);
|
|
97
108
|
|
|
98
109
|
this.timeToCollectAttestations = this.meter.createGauge(Metrics.SEQUENCER_COLLECT_ATTESTATIONS_DURATION);
|
|
99
110
|
|
|
@@ -103,20 +114,56 @@ export class SequencerMetrics {
|
|
|
103
114
|
|
|
104
115
|
this.collectedAttestions = this.meter.createGauge(Metrics.SEQUENCER_COLLECTED_ATTESTATIONS_COUNT);
|
|
105
116
|
|
|
106
|
-
this.blockProposalFailed =
|
|
117
|
+
this.blockProposalFailed = createUpDownCounterWithDefault(
|
|
118
|
+
this.meter,
|
|
119
|
+
Metrics.SEQUENCER_BLOCK_PROPOSAL_FAILED_COUNT,
|
|
120
|
+
);
|
|
107
121
|
|
|
108
|
-
this.
|
|
122
|
+
this.checkpointProposalSuccess = createUpDownCounterWithDefault(
|
|
123
|
+
this.meter,
|
|
124
|
+
Metrics.SEQUENCER_CHECKPOINT_PROPOSAL_SUCCESS_COUNT,
|
|
125
|
+
);
|
|
109
126
|
|
|
110
|
-
this.checkpointSuccess = this.meter
|
|
127
|
+
this.checkpointSuccess = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_CHECKPOINT_SUCCESS_COUNT);
|
|
128
|
+
|
|
129
|
+
this.checkpointPrecheckFailed = createUpDownCounterWithDefault(
|
|
130
|
+
this.meter,
|
|
131
|
+
Metrics.SEQUENCER_CHECKPOINT_PRECHECK_FAILED_COUNT,
|
|
132
|
+
{
|
|
133
|
+
[Attributes.ERROR_TYPE]: [
|
|
134
|
+
'slot_already_taken',
|
|
135
|
+
'rollup_contract_check_failed',
|
|
136
|
+
'slot_mismatch',
|
|
137
|
+
'block_number_mismatch',
|
|
138
|
+
],
|
|
139
|
+
},
|
|
140
|
+
);
|
|
111
141
|
|
|
112
|
-
this.
|
|
113
|
-
|
|
142
|
+
this.checkpointProposalFailed = createUpDownCounterWithDefault(
|
|
143
|
+
this.meter,
|
|
144
|
+
Metrics.SEQUENCER_CHECKPOINT_PROPOSAL_FAILED_COUNT,
|
|
114
145
|
);
|
|
115
146
|
|
|
116
|
-
this.
|
|
147
|
+
this.checkpointBuildDuration = this.meter.createHistogram(Metrics.SEQUENCER_CHECKPOINT_BUILD_DURATION);
|
|
148
|
+
this.checkpointBlockCount = this.meter.createGauge(Metrics.SEQUENCER_CHECKPOINT_BLOCK_COUNT);
|
|
149
|
+
this.checkpointTxCount = this.meter.createGauge(Metrics.SEQUENCER_CHECKPOINT_TX_COUNT);
|
|
150
|
+
this.checkpointTotalMana = this.meter.createGauge(Metrics.SEQUENCER_CHECKPOINT_TOTAL_MANA);
|
|
151
|
+
|
|
152
|
+
this.slashingAttempts = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_SLASHING_ATTEMPTS_COUNT);
|
|
153
|
+
|
|
154
|
+
this.pipelineDepth = this.meter.createGauge(Metrics.SEQUENCER_PIPELINE_DEPTH);
|
|
155
|
+
this.pipelineDiscards = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_PIPELINE_DISCARDS_COUNT);
|
|
156
|
+
this.pipelineDepth.record(0);
|
|
117
157
|
|
|
118
158
|
// Fisherman fee analysis metrics
|
|
119
|
-
this.fishermanWouldBeIncluded =
|
|
159
|
+
this.fishermanWouldBeIncluded = createUpDownCounterWithDefault(
|
|
160
|
+
this.meter,
|
|
161
|
+
Metrics.FISHERMAN_FEE_ANALYSIS_WOULD_BE_INCLUDED,
|
|
162
|
+
{
|
|
163
|
+
[Attributes.OK]: [true, false],
|
|
164
|
+
[Attributes.BLOCK_FULL]: ['true', 'false'],
|
|
165
|
+
},
|
|
166
|
+
);
|
|
120
167
|
|
|
121
168
|
this.fishermanTimeBeforeBlock = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_TIME_BEFORE_BLOCK);
|
|
122
169
|
|
|
@@ -145,6 +192,20 @@ export class SequencerMetrics {
|
|
|
145
192
|
this.fishermanMinedBlobTxTotalCost = this.meter.createHistogram(
|
|
146
193
|
Metrics.FISHERMAN_FEE_ANALYSIS_MINED_BLOB_TX_TOTAL_COST,
|
|
147
194
|
);
|
|
195
|
+
|
|
196
|
+
this.fishermanPendingBlobCount = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_PENDING_BLOB_COUNT);
|
|
197
|
+
|
|
198
|
+
this.fishermanIncludedBlobCount = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_INCLUDED_BLOB_COUNT);
|
|
199
|
+
|
|
200
|
+
this.fishermanBlockBlobsFull = createUpDownCounterWithDefault(
|
|
201
|
+
this.meter,
|
|
202
|
+
Metrics.FISHERMAN_FEE_ANALYSIS_BLOCK_BLOBS_FULL,
|
|
203
|
+
{
|
|
204
|
+
[Attributes.OK]: [true, false],
|
|
205
|
+
},
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
this.fishermanMaxBlobCapacity = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_MAX_BLOB_CAPACITY);
|
|
148
209
|
}
|
|
149
210
|
|
|
150
211
|
public recordRequiredAttestations(requiredAttestationsCount: number, allowanceMs: number) {
|
|
@@ -165,12 +226,20 @@ export class SequencerMetrics {
|
|
|
165
226
|
this.timeToCollectAttestations.record(Math.ceil(durationMs));
|
|
166
227
|
}
|
|
167
228
|
|
|
168
|
-
recordBuiltBlock(buildDurationMs: number, totalMana: number) {
|
|
229
|
+
recordBuiltBlock(buildDurationMs: number, totalMana: number, slot: SlotNumber) {
|
|
169
230
|
this.blockCounter.add(1, {
|
|
170
231
|
[Attributes.STATUS]: 'built',
|
|
171
232
|
});
|
|
172
233
|
this.blockBuildDuration.record(Math.ceil(buildDurationMs));
|
|
173
234
|
this.blockBuildManaPerSecond.record(Math.ceil((totalMana * 1000) / buildDurationMs));
|
|
235
|
+
|
|
236
|
+
// Only record inter-block time between blocks built within the same slot.
|
|
237
|
+
const now = Date.now();
|
|
238
|
+
if (this.lastBlockBuiltTimestamp !== undefined && this.lastBlockBuiltSlot === slot) {
|
|
239
|
+
this.blockInterBlockTime.record(now - this.lastBlockBuiltTimestamp);
|
|
240
|
+
}
|
|
241
|
+
this.lastBlockBuiltTimestamp = now;
|
|
242
|
+
this.lastBlockBuiltSlot = slot;
|
|
174
243
|
}
|
|
175
244
|
|
|
176
245
|
recordFailedBlock() {
|
|
@@ -185,6 +254,14 @@ export class SequencerMetrics {
|
|
|
185
254
|
});
|
|
186
255
|
}
|
|
187
256
|
|
|
257
|
+
recordPipelineDepth(depth: number) {
|
|
258
|
+
this.pipelineDepth.record(depth);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
recordPipelineDiscard(count = 1) {
|
|
262
|
+
this.pipelineDiscards.add(count);
|
|
263
|
+
}
|
|
264
|
+
|
|
188
265
|
incOpenSlot(slot: SlotNumber, proposer: string) {
|
|
189
266
|
// sequencer went through the loop a second time. Noop
|
|
190
267
|
if (slot === this.lastSeenSlot) {
|
|
@@ -227,16 +304,30 @@ export class SequencerMetrics {
|
|
|
227
304
|
});
|
|
228
305
|
}
|
|
229
306
|
|
|
230
|
-
|
|
231
|
-
this.
|
|
307
|
+
recordCheckpointProposalSuccess() {
|
|
308
|
+
this.checkpointProposalSuccess.add(1);
|
|
232
309
|
}
|
|
233
310
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
311
|
+
recordCheckpointPrecheckFailed(
|
|
312
|
+
checkType: 'slot_already_taken' | 'rollup_contract_check_failed' | 'slot_mismatch' | 'block_number_mismatch',
|
|
313
|
+
) {
|
|
314
|
+
this.checkpointPrecheckFailed.add(1, { [Attributes.ERROR_TYPE]: checkType });
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
recordCheckpointProposalFailed(reason?: string) {
|
|
318
|
+
this.checkpointProposalFailed.add(1, {
|
|
319
|
+
...(reason && { [Attributes.ERROR_TYPE]: reason }),
|
|
237
320
|
});
|
|
238
321
|
}
|
|
239
322
|
|
|
323
|
+
/** Records aggregate metrics for a completed checkpoint build. */
|
|
324
|
+
recordCheckpointBuild(durationMs: number, blockCount: number, txCount: number, totalMana: number) {
|
|
325
|
+
this.checkpointBuildDuration.record(Math.ceil(durationMs));
|
|
326
|
+
this.checkpointBlockCount.record(blockCount);
|
|
327
|
+
this.checkpointTxCount.record(txCount);
|
|
328
|
+
this.checkpointTotalMana.record(totalMana);
|
|
329
|
+
}
|
|
330
|
+
|
|
240
331
|
recordSlashingAttempt(actionCount: number) {
|
|
241
332
|
this.slashingAttempts.add(actionCount);
|
|
242
333
|
}
|
|
@@ -263,10 +354,12 @@ export class SequencerMetrics {
|
|
|
263
354
|
|
|
264
355
|
// Record pending block snapshot data (once per strategy for comparison)
|
|
265
356
|
this.fishermanPendingBlobTxCount.record(analysis.pendingSnapshot.pendingBlobTxCount, strategyAttributes);
|
|
357
|
+
this.fishermanPendingBlobCount.record(analysis.pendingSnapshot.pendingBlobCount, strategyAttributes);
|
|
266
358
|
|
|
267
359
|
// Record mined block data if available
|
|
268
360
|
if (analysis.minedBlock) {
|
|
269
361
|
this.fishermanIncludedBlobTxCount.record(analysis.minedBlock.includedBlobTxCount, strategyAttributes);
|
|
362
|
+
this.fishermanIncludedBlobCount.record(analysis.minedBlock.includedBlobCount, strategyAttributes);
|
|
270
363
|
|
|
271
364
|
// Record actual fees from blob transactions in the mined block
|
|
272
365
|
for (const blobTx of analysis.minedBlock.includedBlobTxs) {
|
|
@@ -300,13 +393,28 @@ export class SequencerMetrics {
|
|
|
300
393
|
if (analysis.analysis) {
|
|
301
394
|
this.fishermanTimeBeforeBlock.record(Math.ceil(analysis.analysis.timeBeforeBlockMs), strategyAttributes);
|
|
302
395
|
|
|
396
|
+
// Record whether the block reached 100% blob capacity
|
|
397
|
+
if (analysis.analysis.blockBlobsFull) {
|
|
398
|
+
this.fishermanBlockBlobsFull.add(1, { ...strategyAttributes, [Attributes.OK]: true });
|
|
399
|
+
} else {
|
|
400
|
+
this.fishermanBlockBlobsFull.add(1, { ...strategyAttributes, [Attributes.OK]: false });
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Record the max blob capacity for this block
|
|
404
|
+
this.fishermanMaxBlobCapacity.record(analysis.analysis.maxBlobCapacity, strategyAttributes);
|
|
405
|
+
|
|
303
406
|
// Record strategy-specific inclusion result
|
|
304
407
|
if (strategyResult.wouldBeIncluded !== undefined) {
|
|
408
|
+
const inclusionAttributes = {
|
|
409
|
+
...strategyAttributes,
|
|
410
|
+
[Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false',
|
|
411
|
+
};
|
|
412
|
+
|
|
305
413
|
if (strategyResult.wouldBeIncluded) {
|
|
306
|
-
this.fishermanWouldBeIncluded.add(1, { ...
|
|
414
|
+
this.fishermanWouldBeIncluded.add(1, { ...inclusionAttributes, [Attributes.OK]: true });
|
|
307
415
|
} else {
|
|
308
416
|
this.fishermanWouldBeIncluded.add(1, {
|
|
309
|
-
...
|
|
417
|
+
...inclusionAttributes,
|
|
310
418
|
[Attributes.OK]: false,
|
|
311
419
|
...(strategyResult.exclusionReason && { [Attributes.ERROR_TYPE]: strategyResult.exclusionReason }),
|
|
312
420
|
});
|
|
@@ -316,17 +424,29 @@ export class SequencerMetrics {
|
|
|
316
424
|
// Record strategy-specific priority fee delta
|
|
317
425
|
if (strategyResult.priorityFeeDelta !== undefined) {
|
|
318
426
|
const priorityFeeDeltaGwei = Number(strategyResult.priorityFeeDelta) / 1e9;
|
|
319
|
-
|
|
427
|
+
const deltaAttributes = {
|
|
428
|
+
...strategyAttributes,
|
|
429
|
+
[Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false',
|
|
430
|
+
};
|
|
431
|
+
this.fishermanPriorityFeeDelta.record(priorityFeeDeltaGwei, deltaAttributes);
|
|
320
432
|
}
|
|
321
433
|
|
|
322
434
|
// Record estimated cost if available
|
|
323
435
|
if (strategyResult.estimatedCostEth !== undefined) {
|
|
324
|
-
|
|
436
|
+
const costAttributes = {
|
|
437
|
+
...strategyAttributes,
|
|
438
|
+
[Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false',
|
|
439
|
+
};
|
|
440
|
+
this.fishermanEstimatedCost.record(strategyResult.estimatedCostEth, costAttributes);
|
|
325
441
|
}
|
|
326
442
|
|
|
327
443
|
// Record estimated overpayment if available
|
|
328
444
|
if (strategyResult.estimatedOverpaymentEth !== undefined) {
|
|
329
|
-
|
|
445
|
+
const overpaymentAttributes = {
|
|
446
|
+
...strategyAttributes,
|
|
447
|
+
[Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false',
|
|
448
|
+
};
|
|
449
|
+
this.fishermanEstimatedOverpayment.record(strategyResult.estimatedOverpaymentEth, overpaymentAttributes);
|
|
330
450
|
}
|
|
331
451
|
}
|
|
332
452
|
}
|