@aztec/sequencer-client 0.0.1-commit.03f7ef2 → 0.0.1-commit.08c5969dc
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 +5 -6
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +1 -1
- package/dest/config.d.ts +1 -2
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +10 -9
- 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 +13 -13
- 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-factory.d.ts +2 -2
- package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
- 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 +23 -86
- package/dest/publisher/sequencer-publisher.d.ts +19 -19
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +482 -71
- package/dest/sequencer/checkpoint_proposal_job.d.ts +40 -12
- package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_proposal_job.js +610 -59
- package/dest/sequencer/checkpoint_voter.d.ts +3 -2
- package/dest/sequencer/checkpoint_voter.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_voter.js +34 -10
- package/dest/sequencer/index.d.ts +1 -3
- package/dest/sequencer/index.d.ts.map +1 -1
- package/dest/sequencer/index.js +0 -2
- package/dest/sequencer/metrics.d.ts +7 -4
- package/dest/sequencer/metrics.d.ts.map +1 -1
- package/dest/sequencer/metrics.js +72 -128
- package/dest/sequencer/sequencer.d.ts +27 -15
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +492 -43
- package/dest/sequencer/timetable.d.ts +1 -4
- package/dest/sequencer/timetable.d.ts.map +1 -1
- package/dest/sequencer/timetable.js +1 -4
- 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 +23 -11
- package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
- package/dest/test/mock_checkpoint_builder.js +50 -9
- package/dest/test/utils.d.ts +13 -9
- package/dest/test/utils.d.ts.map +1 -1
- package/dest/test/utils.js +27 -17
- package/package.json +30 -28
- package/src/client/sequencer-client.ts +5 -6
- package/src/config.ts +14 -11
- package/src/global_variable_builder/global_builder.ts +13 -13
- package/src/index.ts +1 -9
- package/src/publisher/sequencer-publisher-factory.ts +1 -1
- package/src/publisher/sequencer-publisher-metrics.ts +17 -69
- package/src/publisher/sequencer-publisher.ts +121 -95
- package/src/sequencer/checkpoint_proposal_job.ts +263 -89
- package/src/sequencer/checkpoint_voter.ts +32 -7
- package/src/sequencer/index.ts +0 -2
- package/src/sequencer/metrics.ts +70 -136
- package/src/sequencer/sequencer.ts +133 -43
- package/src/sequencer/timetable.ts +6 -5
- package/src/test/index.ts +1 -2
- package/src/test/mock_checkpoint_builder.ts +91 -29
- package/src/test/utils.ts +56 -28
- package/dest/sequencer/block_builder.d.ts +0 -26
- package/dest/sequencer/block_builder.d.ts.map +0 -1
- package/dest/sequencer/block_builder.js +0 -129
- 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/block_builder.ts +0 -217
- 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
|
@@ -5,6 +5,8 @@ import type { SlasherClientInterface } from '@aztec/slasher';
|
|
|
5
5
|
import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
6
6
|
import type { ResolvedSequencerConfig } from '@aztec/stdlib/interfaces/server';
|
|
7
7
|
import type { ValidatorClient } from '@aztec/validator-client';
|
|
8
|
+
import { DutyAlreadySignedError } from '@aztec/validator-ha-signer/errors';
|
|
9
|
+
import { DutyType, type SigningContext } from '@aztec/validator-ha-signer/types';
|
|
8
10
|
|
|
9
11
|
import type { TypedDataDefinition } from 'viem';
|
|
10
12
|
|
|
@@ -17,7 +19,8 @@ import type { SequencerRollupConstants } from './types.js';
|
|
|
17
19
|
*/
|
|
18
20
|
export class CheckpointVoter {
|
|
19
21
|
private slotTimestamp: bigint;
|
|
20
|
-
private
|
|
22
|
+
private governanceSigner: (msg: TypedDataDefinition) => Promise<`0x${string}`>;
|
|
23
|
+
private slashingSigner: (msg: TypedDataDefinition) => Promise<`0x${string}`>;
|
|
21
24
|
|
|
22
25
|
constructor(
|
|
23
26
|
private readonly slot: SlotNumber,
|
|
@@ -31,8 +34,16 @@ export class CheckpointVoter {
|
|
|
31
34
|
private readonly log: Logger,
|
|
32
35
|
) {
|
|
33
36
|
this.slotTimestamp = getTimestampForSlot(this.slot, this.l1Constants);
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
|
|
38
|
+
// Create separate signers with appropriate duty contexts for governance and slashing votes
|
|
39
|
+
// These use HA protection to ensure only one node signs per slot/duty
|
|
40
|
+
const governanceContext: SigningContext = { slot: this.slot, dutyType: DutyType.GOVERNANCE_VOTE };
|
|
41
|
+
this.governanceSigner = (msg: TypedDataDefinition) =>
|
|
42
|
+
this.validatorClient.signWithAddress(this.attestorAddress, msg, governanceContext).then(s => s.toString());
|
|
43
|
+
|
|
44
|
+
const slashingContext: SigningContext = { slot: this.slot, dutyType: DutyType.SLASHING_VOTE };
|
|
45
|
+
this.slashingSigner = (msg: TypedDataDefinition) =>
|
|
46
|
+
this.validatorClient.signWithAddress(this.attestorAddress, msg, slashingContext).then(s => s.toString());
|
|
36
47
|
}
|
|
37
48
|
|
|
38
49
|
/**
|
|
@@ -68,10 +79,17 @@ export class CheckpointVoter {
|
|
|
68
79
|
this.slot,
|
|
69
80
|
this.slotTimestamp,
|
|
70
81
|
this.attestorAddress,
|
|
71
|
-
this.
|
|
82
|
+
this.governanceSigner,
|
|
72
83
|
);
|
|
73
84
|
} catch (err) {
|
|
74
|
-
|
|
85
|
+
if (err instanceof DutyAlreadySignedError) {
|
|
86
|
+
this.log.info(`Governance vote already signed by another node`, {
|
|
87
|
+
slot: this.slot,
|
|
88
|
+
signedByNode: err.signedByNode,
|
|
89
|
+
});
|
|
90
|
+
} else {
|
|
91
|
+
this.log.error(`Error enqueueing governance vote`, err);
|
|
92
|
+
}
|
|
75
93
|
return false;
|
|
76
94
|
}
|
|
77
95
|
}
|
|
@@ -95,10 +113,17 @@ export class CheckpointVoter {
|
|
|
95
113
|
this.slot,
|
|
96
114
|
this.slotTimestamp,
|
|
97
115
|
this.attestorAddress,
|
|
98
|
-
this.
|
|
116
|
+
this.slashingSigner,
|
|
99
117
|
);
|
|
100
118
|
} catch (err) {
|
|
101
|
-
|
|
119
|
+
if (err instanceof DutyAlreadySignedError) {
|
|
120
|
+
this.log.info(`Slashing vote already signed by another node`, {
|
|
121
|
+
slot: this.slot,
|
|
122
|
+
signedByNode: err.signedByNode,
|
|
123
|
+
});
|
|
124
|
+
} else {
|
|
125
|
+
this.log.error(`Error enqueueing slashing vote`, err);
|
|
126
|
+
}
|
|
102
127
|
return false;
|
|
103
128
|
}
|
|
104
129
|
}
|
package/src/sequencer/index.ts
CHANGED
package/src/sequencer/metrics.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
type TelemetryClient,
|
|
12
12
|
type Tracer,
|
|
13
13
|
type UpDownCounter,
|
|
14
|
-
|
|
14
|
+
createUpDownCounterWithDefault,
|
|
15
15
|
} from '@aztec/telemetry-client';
|
|
16
16
|
|
|
17
17
|
import { type Hex, formatUnits } from 'viem';
|
|
@@ -44,13 +44,16 @@ export class SequencerMetrics {
|
|
|
44
44
|
private blockProposalPrecheckFailed: UpDownCounter;
|
|
45
45
|
private checkpointSuccess: UpDownCounter;
|
|
46
46
|
private slashingAttempts: UpDownCounter;
|
|
47
|
-
private
|
|
47
|
+
private checkpointAttestationDelay: Histogram;
|
|
48
48
|
|
|
49
49
|
// Fisherman fee analysis metrics
|
|
50
50
|
private fishermanWouldBeIncluded: UpDownCounter;
|
|
51
51
|
private fishermanTimeBeforeBlock: Histogram;
|
|
52
52
|
private fishermanPendingBlobTxCount: Histogram;
|
|
53
53
|
private fishermanIncludedBlobTxCount: Histogram;
|
|
54
|
+
private fishermanPendingBlobCount: Histogram;
|
|
55
|
+
private fishermanIncludedBlobCount: Histogram;
|
|
56
|
+
private fishermanBlockBlobsFull: UpDownCounter;
|
|
54
57
|
private fishermanCalculatedPriorityFee: Histogram;
|
|
55
58
|
private fishermanPriorityFeeDelta: Histogram;
|
|
56
59
|
private fishermanEstimatedCost: Histogram;
|
|
@@ -68,189 +71,109 @@ export class SequencerMetrics {
|
|
|
68
71
|
this.meter = client.getMeter(name);
|
|
69
72
|
this.tracer = client.getTracer(name);
|
|
70
73
|
|
|
71
|
-
this.blockCounter = this.meter
|
|
72
|
-
|
|
73
|
-
this.blockBuildDuration = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_DURATION, {
|
|
74
|
-
unit: 'ms',
|
|
75
|
-
description: 'Duration to build a block',
|
|
76
|
-
valueType: ValueType.INT,
|
|
74
|
+
this.blockCounter = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_BLOCK_COUNT, {
|
|
75
|
+
[Attributes.STATUS]: ['failed', 'built'],
|
|
77
76
|
});
|
|
78
77
|
|
|
79
|
-
this.
|
|
80
|
-
unit: 'mana/s',
|
|
81
|
-
description: 'Mana per second when building a block',
|
|
82
|
-
valueType: ValueType.INT,
|
|
83
|
-
});
|
|
78
|
+
this.blockBuildDuration = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_DURATION);
|
|
84
79
|
|
|
85
|
-
this.
|
|
86
|
-
Metrics.SEQUENCER_STATE_TRANSITION_BUFFER_DURATION,
|
|
87
|
-
{
|
|
88
|
-
unit: 'ms',
|
|
89
|
-
description:
|
|
90
|
-
'The time difference between when the sequencer needed to transition to a new state and when it actually did.',
|
|
91
|
-
valueType: ValueType.INT,
|
|
92
|
-
},
|
|
93
|
-
);
|
|
80
|
+
this.blockBuildManaPerSecond = this.meter.createGauge(Metrics.SEQUENCER_BLOCK_BUILD_MANA_PER_SECOND);
|
|
94
81
|
|
|
95
|
-
this.
|
|
96
|
-
unit: 'ms',
|
|
97
|
-
description: 'The time difference between block proposal and minimal attestation count reached,',
|
|
98
|
-
valueType: ValueType.INT,
|
|
99
|
-
});
|
|
82
|
+
this.stateTransitionBufferDuration = this.meter.createHistogram(Metrics.SEQUENCER_STATE_TRANSITION_BUFFER_DURATION);
|
|
100
83
|
|
|
101
|
-
|
|
102
|
-
this.blockCounter.add(0, {
|
|
103
|
-
[Attributes.STATUS]: 'failed',
|
|
104
|
-
});
|
|
105
|
-
this.blockCounter.add(0, {
|
|
106
|
-
[Attributes.STATUS]: 'built',
|
|
107
|
-
});
|
|
84
|
+
this.checkpointAttestationDelay = this.meter.createHistogram(Metrics.SEQUENCER_CHECKPOINT_ATTESTATION_DELAY);
|
|
108
85
|
|
|
109
|
-
this.rewards = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_REWARDS
|
|
110
|
-
valueType: ValueType.DOUBLE,
|
|
111
|
-
description: 'The rewards earned',
|
|
112
|
-
});
|
|
86
|
+
this.rewards = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_REWARDS);
|
|
113
87
|
|
|
114
|
-
this.slots = this.meter
|
|
115
|
-
valueType: ValueType.INT,
|
|
116
|
-
description: 'The number of slots this sequencer was selected for',
|
|
117
|
-
});
|
|
88
|
+
this.slots = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_SLOT_COUNT);
|
|
118
89
|
|
|
119
90
|
/**
|
|
120
91
|
* NOTE: we do not track missed slots as a separate metric. That would be difficult to determine
|
|
121
92
|
* Instead, use a computed metric, `slots - filledSlots` to get the number of slots a sequencer has missed.
|
|
122
93
|
*/
|
|
123
|
-
this.filledSlots = this.meter
|
|
124
|
-
valueType: ValueType.INT,
|
|
125
|
-
description: 'The number of slots this sequencer has filled',
|
|
126
|
-
});
|
|
94
|
+
this.filledSlots = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_FILLED_SLOT_COUNT);
|
|
127
95
|
|
|
128
|
-
this.timeToCollectAttestations = this.meter.createGauge(Metrics.SEQUENCER_COLLECT_ATTESTATIONS_DURATION
|
|
129
|
-
description: 'The time spent collecting attestations from committee members',
|
|
130
|
-
unit: 'ms',
|
|
131
|
-
valueType: ValueType.INT,
|
|
132
|
-
});
|
|
96
|
+
this.timeToCollectAttestations = this.meter.createGauge(Metrics.SEQUENCER_COLLECT_ATTESTATIONS_DURATION);
|
|
133
97
|
|
|
134
|
-
this.allowanceToCollectAttestations = this.meter.createGauge(
|
|
135
|
-
Metrics.SEQUENCER_COLLECT_ATTESTATIONS_TIME_ALLOWANCE,
|
|
136
|
-
{
|
|
137
|
-
description: 'Maximum amount of time to collect attestations',
|
|
138
|
-
unit: 'ms',
|
|
139
|
-
valueType: ValueType.INT,
|
|
140
|
-
},
|
|
141
|
-
);
|
|
98
|
+
this.allowanceToCollectAttestations = this.meter.createGauge(Metrics.SEQUENCER_COLLECT_ATTESTATIONS_TIME_ALLOWANCE);
|
|
142
99
|
|
|
143
|
-
this.requiredAttestions = this.meter.createGauge(Metrics.SEQUENCER_REQUIRED_ATTESTATIONS_COUNT
|
|
144
|
-
valueType: ValueType.INT,
|
|
145
|
-
description: 'The minimum number of attestations required to publish a block',
|
|
146
|
-
});
|
|
100
|
+
this.requiredAttestions = this.meter.createGauge(Metrics.SEQUENCER_REQUIRED_ATTESTATIONS_COUNT);
|
|
147
101
|
|
|
148
|
-
this.collectedAttestions = this.meter.createGauge(Metrics.SEQUENCER_COLLECTED_ATTESTATIONS_COUNT
|
|
149
|
-
valueType: ValueType.INT,
|
|
150
|
-
description: 'The minimum number of attestations required to publish a block',
|
|
151
|
-
});
|
|
102
|
+
this.collectedAttestions = this.meter.createGauge(Metrics.SEQUENCER_COLLECTED_ATTESTATIONS_COUNT);
|
|
152
103
|
|
|
153
|
-
this.blockProposalFailed =
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
104
|
+
this.blockProposalFailed = createUpDownCounterWithDefault(
|
|
105
|
+
this.meter,
|
|
106
|
+
Metrics.SEQUENCER_BLOCK_PROPOSAL_FAILED_COUNT,
|
|
107
|
+
);
|
|
157
108
|
|
|
158
|
-
this.blockProposalSuccess =
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
109
|
+
this.blockProposalSuccess = createUpDownCounterWithDefault(
|
|
110
|
+
this.meter,
|
|
111
|
+
Metrics.SEQUENCER_BLOCK_PROPOSAL_SUCCESS_COUNT,
|
|
112
|
+
);
|
|
162
113
|
|
|
163
|
-
this.checkpointSuccess = this.meter
|
|
164
|
-
valueType: ValueType.INT,
|
|
165
|
-
description: 'The number of times checkpoint publishing succeeded',
|
|
166
|
-
});
|
|
114
|
+
this.checkpointSuccess = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_CHECKPOINT_SUCCESS_COUNT);
|
|
167
115
|
|
|
168
|
-
this.blockProposalPrecheckFailed =
|
|
116
|
+
this.blockProposalPrecheckFailed = createUpDownCounterWithDefault(
|
|
117
|
+
this.meter,
|
|
169
118
|
Metrics.SEQUENCER_BLOCK_PROPOSAL_PRECHECK_FAILED_COUNT,
|
|
170
119
|
{
|
|
171
|
-
|
|
172
|
-
|
|
120
|
+
[Attributes.ERROR_TYPE]: [
|
|
121
|
+
'slot_already_taken',
|
|
122
|
+
'rollup_contract_check_failed',
|
|
123
|
+
'slot_mismatch',
|
|
124
|
+
'block_number_mismatch',
|
|
125
|
+
],
|
|
173
126
|
},
|
|
174
127
|
);
|
|
175
128
|
|
|
176
|
-
this.slashingAttempts = this.meter
|
|
177
|
-
valueType: ValueType.INT,
|
|
178
|
-
description: 'The number of slashing action attempts',
|
|
179
|
-
});
|
|
129
|
+
this.slashingAttempts = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_SLASHING_ATTEMPTS_COUNT);
|
|
180
130
|
|
|
181
131
|
// Fisherman fee analysis metrics
|
|
182
|
-
this.fishermanWouldBeIncluded =
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
this.fishermanTimeBeforeBlock = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_TIME_BEFORE_BLOCK, {
|
|
188
|
-
unit: 'ms',
|
|
189
|
-
description: 'Time in ms between fee analysis and block being mined',
|
|
190
|
-
valueType: ValueType.INT,
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
this.fishermanPendingBlobTxCount = this.meter.createHistogram(
|
|
194
|
-
Metrics.FISHERMAN_FEE_ANALYSIS_PENDING_BLOB_TX_COUNT,
|
|
132
|
+
this.fishermanWouldBeIncluded = createUpDownCounterWithDefault(
|
|
133
|
+
this.meter,
|
|
134
|
+
Metrics.FISHERMAN_FEE_ANALYSIS_WOULD_BE_INCLUDED,
|
|
195
135
|
{
|
|
196
|
-
|
|
197
|
-
valueType: ValueType.INT,
|
|
136
|
+
[Attributes.OK]: [true, false],
|
|
198
137
|
},
|
|
199
138
|
);
|
|
200
139
|
|
|
140
|
+
this.fishermanTimeBeforeBlock = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_TIME_BEFORE_BLOCK);
|
|
141
|
+
|
|
142
|
+
this.fishermanPendingBlobTxCount = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_PENDING_BLOB_TX_COUNT);
|
|
143
|
+
|
|
201
144
|
this.fishermanIncludedBlobTxCount = this.meter.createHistogram(
|
|
202
145
|
Metrics.FISHERMAN_FEE_ANALYSIS_INCLUDED_BLOB_TX_COUNT,
|
|
203
|
-
{
|
|
204
|
-
description: 'Number of blob transactions that got included in the mined block',
|
|
205
|
-
valueType: ValueType.INT,
|
|
206
|
-
},
|
|
207
146
|
);
|
|
208
147
|
|
|
209
148
|
this.fishermanCalculatedPriorityFee = this.meter.createHistogram(
|
|
210
149
|
Metrics.FISHERMAN_FEE_ANALYSIS_CALCULATED_PRIORITY_FEE,
|
|
211
|
-
{
|
|
212
|
-
unit: 'gwei',
|
|
213
|
-
description: 'Priority fee calculated by each strategy',
|
|
214
|
-
valueType: ValueType.DOUBLE,
|
|
215
|
-
},
|
|
216
150
|
);
|
|
217
151
|
|
|
218
|
-
this.fishermanPriorityFeeDelta = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_PRIORITY_FEE_DELTA
|
|
219
|
-
unit: 'gwei',
|
|
220
|
-
description: 'Difference between our priority fee and minimum included priority fee',
|
|
221
|
-
valueType: ValueType.DOUBLE,
|
|
222
|
-
});
|
|
152
|
+
this.fishermanPriorityFeeDelta = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_PRIORITY_FEE_DELTA);
|
|
223
153
|
|
|
224
|
-
this.fishermanEstimatedCost = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_ESTIMATED_COST
|
|
225
|
-
unit: 'eth',
|
|
226
|
-
description: 'Estimated total cost in ETH for the transaction with this strategy',
|
|
227
|
-
valueType: ValueType.DOUBLE,
|
|
228
|
-
});
|
|
154
|
+
this.fishermanEstimatedCost = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_ESTIMATED_COST);
|
|
229
155
|
|
|
230
156
|
this.fishermanEstimatedOverpayment = this.meter.createHistogram(
|
|
231
157
|
Metrics.FISHERMAN_FEE_ANALYSIS_ESTIMATED_OVERPAYMENT,
|
|
232
|
-
{
|
|
233
|
-
unit: 'eth',
|
|
234
|
-
description: 'Estimated overpayment in ETH vs minimum required for inclusion',
|
|
235
|
-
valueType: ValueType.DOUBLE,
|
|
236
|
-
},
|
|
237
158
|
);
|
|
238
159
|
|
|
239
160
|
this.fishermanMinedBlobTxPriorityFee = this.meter.createHistogram(
|
|
240
161
|
Metrics.FISHERMAN_FEE_ANALYSIS_MINED_BLOB_TX_PRIORITY_FEE,
|
|
241
|
-
{
|
|
242
|
-
unit: 'gwei',
|
|
243
|
-
description: 'Priority fee per gas for blob transactions in mined blocks',
|
|
244
|
-
valueType: ValueType.DOUBLE,
|
|
245
|
-
},
|
|
246
162
|
);
|
|
247
163
|
|
|
248
164
|
this.fishermanMinedBlobTxTotalCost = this.meter.createHistogram(
|
|
249
165
|
Metrics.FISHERMAN_FEE_ANALYSIS_MINED_BLOB_TX_TOTAL_COST,
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
this.fishermanPendingBlobCount = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_PENDING_BLOB_COUNT);
|
|
169
|
+
|
|
170
|
+
this.fishermanIncludedBlobCount = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_INCLUDED_BLOB_COUNT);
|
|
171
|
+
|
|
172
|
+
this.fishermanBlockBlobsFull = createUpDownCounterWithDefault(
|
|
173
|
+
this.meter,
|
|
174
|
+
Metrics.FISHERMAN_FEE_ANALYSIS_BLOCK_BLOBS_FULL,
|
|
250
175
|
{
|
|
251
|
-
|
|
252
|
-
description: 'Total cost in ETH for blob transactions in mined blocks',
|
|
253
|
-
valueType: ValueType.DOUBLE,
|
|
176
|
+
[Attributes.OK]: [true, false],
|
|
254
177
|
},
|
|
255
178
|
);
|
|
256
179
|
}
|
|
@@ -264,8 +187,8 @@ export class SequencerMetrics {
|
|
|
264
187
|
this.timeToCollectAttestations.record(0);
|
|
265
188
|
}
|
|
266
189
|
|
|
267
|
-
public
|
|
268
|
-
this.
|
|
190
|
+
public recordCheckpointAttestationDelay(duration: number) {
|
|
191
|
+
this.checkpointAttestationDelay.record(duration);
|
|
269
192
|
}
|
|
270
193
|
|
|
271
194
|
public recordCollectedAttestations(count: number, durationMs: number) {
|
|
@@ -339,7 +262,9 @@ export class SequencerMetrics {
|
|
|
339
262
|
this.blockProposalSuccess.add(1);
|
|
340
263
|
}
|
|
341
264
|
|
|
342
|
-
recordBlockProposalPrecheckFailed(
|
|
265
|
+
recordBlockProposalPrecheckFailed(
|
|
266
|
+
checkType: 'slot_already_taken' | 'rollup_contract_check_failed' | 'slot_mismatch' | 'block_number_mismatch',
|
|
267
|
+
) {
|
|
343
268
|
this.blockProposalPrecheckFailed.add(1, {
|
|
344
269
|
[Attributes.ERROR_TYPE]: checkType,
|
|
345
270
|
});
|
|
@@ -371,10 +296,12 @@ export class SequencerMetrics {
|
|
|
371
296
|
|
|
372
297
|
// Record pending block snapshot data (once per strategy for comparison)
|
|
373
298
|
this.fishermanPendingBlobTxCount.record(analysis.pendingSnapshot.pendingBlobTxCount, strategyAttributes);
|
|
299
|
+
this.fishermanPendingBlobCount.record(analysis.pendingSnapshot.pendingBlobCount, strategyAttributes);
|
|
374
300
|
|
|
375
301
|
// Record mined block data if available
|
|
376
302
|
if (analysis.minedBlock) {
|
|
377
303
|
this.fishermanIncludedBlobTxCount.record(analysis.minedBlock.includedBlobTxCount, strategyAttributes);
|
|
304
|
+
this.fishermanIncludedBlobCount.record(analysis.minedBlock.includedBlobCount, strategyAttributes);
|
|
378
305
|
|
|
379
306
|
// Record actual fees from blob transactions in the mined block
|
|
380
307
|
for (const blobTx of analysis.minedBlock.includedBlobTxs) {
|
|
@@ -408,6 +335,13 @@ export class SequencerMetrics {
|
|
|
408
335
|
if (analysis.analysis) {
|
|
409
336
|
this.fishermanTimeBeforeBlock.record(Math.ceil(analysis.analysis.timeBeforeBlockMs), strategyAttributes);
|
|
410
337
|
|
|
338
|
+
// Record whether the block reached 100% blob capacity
|
|
339
|
+
if (analysis.analysis.blockBlobsFull) {
|
|
340
|
+
this.fishermanBlockBlobsFull.add(1, { ...strategyAttributes, [Attributes.OK]: true });
|
|
341
|
+
} else {
|
|
342
|
+
this.fishermanBlockBlobsFull.add(1, { ...strategyAttributes, [Attributes.OK]: false });
|
|
343
|
+
}
|
|
344
|
+
|
|
411
345
|
// Record strategy-specific inclusion result
|
|
412
346
|
if (strategyResult.wouldBeIncluded !== undefined) {
|
|
413
347
|
if (strategyResult.wouldBeIncluded) {
|