@aztec/sequencer-client 0.0.1-commit.03f7ef2 → 0.0.1-commit.04d373f

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.
Files changed (145) hide show
  1. package/README.md +282 -21
  2. package/dest/client/sequencer-client.d.ts +20 -11
  3. package/dest/client/sequencer-client.d.ts.map +1 -1
  4. package/dest/client/sequencer-client.js +67 -33
  5. package/dest/config.d.ts +29 -7
  6. package/dest/config.d.ts.map +1 -1
  7. package/dest/config.js +82 -37
  8. package/dest/global_variable_builder/fee_predictor.d.ts +37 -0
  9. package/dest/global_variable_builder/fee_predictor.d.ts.map +1 -0
  10. package/dest/global_variable_builder/fee_predictor.js +128 -0
  11. package/dest/global_variable_builder/fee_provider.d.ts +21 -0
  12. package/dest/global_variable_builder/fee_provider.d.ts.map +1 -0
  13. package/dest/global_variable_builder/fee_provider.js +58 -0
  14. package/dest/global_variable_builder/global_builder.d.ts +14 -16
  15. package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
  16. package/dest/global_variable_builder/global_builder.js +16 -50
  17. package/dest/global_variable_builder/index.d.ts +4 -2
  18. package/dest/global_variable_builder/index.d.ts.map +1 -1
  19. package/dest/global_variable_builder/index.js +2 -0
  20. package/dest/index.d.ts +2 -3
  21. package/dest/index.d.ts.map +1 -1
  22. package/dest/index.js +1 -2
  23. package/dest/publisher/config.d.ts +47 -17
  24. package/dest/publisher/config.d.ts.map +1 -1
  25. package/dest/publisher/config.js +121 -42
  26. package/dest/publisher/index.d.ts +2 -1
  27. package/dest/publisher/index.d.ts.map +1 -1
  28. package/dest/publisher/l1_tx_failed_store/factory.d.ts +11 -0
  29. package/dest/publisher/l1_tx_failed_store/factory.d.ts.map +1 -0
  30. package/dest/publisher/l1_tx_failed_store/factory.js +22 -0
  31. package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts +58 -0
  32. package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts.map +1 -0
  33. package/dest/publisher/l1_tx_failed_store/failed_tx_store.js +1 -0
  34. package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts +15 -0
  35. package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts.map +1 -0
  36. package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.js +34 -0
  37. package/dest/publisher/l1_tx_failed_store/index.d.ts +4 -0
  38. package/dest/publisher/l1_tx_failed_store/index.d.ts.map +1 -0
  39. package/dest/publisher/l1_tx_failed_store/index.js +2 -0
  40. package/dest/publisher/sequencer-bundle-simulator.d.ts +96 -0
  41. package/dest/publisher/sequencer-bundle-simulator.d.ts.map +1 -0
  42. package/dest/publisher/sequencer-bundle-simulator.js +198 -0
  43. package/dest/publisher/sequencer-publisher-factory.d.ts +12 -6
  44. package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
  45. package/dest/publisher/sequencer-publisher-factory.js +27 -3
  46. package/dest/publisher/sequencer-publisher-metrics.d.ts +1 -1
  47. package/dest/publisher/sequencer-publisher-metrics.d.ts.map +1 -1
  48. package/dest/publisher/sequencer-publisher-metrics.js +23 -86
  49. package/dest/publisher/sequencer-publisher.d.ts +108 -81
  50. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  51. package/dest/publisher/sequencer-publisher.js +876 -403
  52. package/dest/sequencer/automine/automine_factory.d.ts +54 -0
  53. package/dest/sequencer/automine/automine_factory.d.ts.map +1 -0
  54. package/dest/sequencer/automine/automine_factory.js +84 -0
  55. package/dest/sequencer/automine/automine_sequencer.d.ts +151 -0
  56. package/dest/sequencer/automine/automine_sequencer.d.ts.map +1 -0
  57. package/dest/sequencer/automine/automine_sequencer.js +506 -0
  58. package/dest/sequencer/chain_state_overrides.d.ts +61 -0
  59. package/dest/sequencer/chain_state_overrides.d.ts.map +1 -0
  60. package/dest/sequencer/chain_state_overrides.js +98 -0
  61. package/dest/sequencer/checkpoint_proposal_job.d.ts +87 -16
  62. package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
  63. package/dest/sequencer/checkpoint_proposal_job.js +1331 -203
  64. package/dest/sequencer/checkpoint_proposal_job_metrics.d.ts +34 -0
  65. package/dest/sequencer/checkpoint_proposal_job_metrics.d.ts.map +1 -0
  66. package/dest/sequencer/checkpoint_proposal_job_metrics.js +72 -0
  67. package/dest/sequencer/checkpoint_voter.d.ts +3 -3
  68. package/dest/sequencer/checkpoint_voter.d.ts.map +1 -1
  69. package/dest/sequencer/checkpoint_voter.js +34 -13
  70. package/dest/sequencer/events.d.ts +47 -2
  71. package/dest/sequencer/events.d.ts.map +1 -1
  72. package/dest/sequencer/index.d.ts +3 -3
  73. package/dest/sequencer/index.d.ts.map +1 -1
  74. package/dest/sequencer/index.js +2 -2
  75. package/dest/sequencer/metrics.d.ts +23 -8
  76. package/dest/sequencer/metrics.d.ts.map +1 -1
  77. package/dest/sequencer/metrics.js +158 -143
  78. package/dest/sequencer/sequencer.d.ts +92 -29
  79. package/dest/sequencer/sequencer.d.ts.map +1 -1
  80. package/dest/sequencer/sequencer.js +818 -157
  81. package/dest/sequencer/timetable.d.ts +17 -6
  82. package/dest/sequencer/timetable.d.ts.map +1 -1
  83. package/dest/sequencer/timetable.js +51 -46
  84. package/dest/sequencer/types.d.ts +2 -2
  85. package/dest/sequencer/types.d.ts.map +1 -1
  86. package/dest/test/index.d.ts +4 -7
  87. package/dest/test/index.d.ts.map +1 -1
  88. package/dest/test/mock_checkpoint_builder.d.ts +29 -17
  89. package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
  90. package/dest/test/mock_checkpoint_builder.js +86 -34
  91. package/dest/test/utils.d.ts +13 -9
  92. package/dest/test/utils.d.ts.map +1 -1
  93. package/dest/test/utils.js +31 -20
  94. package/package.json +29 -28
  95. package/src/client/sequencer-client.ts +94 -38
  96. package/src/config.ts +107 -46
  97. package/src/global_variable_builder/README.md +44 -0
  98. package/src/global_variable_builder/fee_predictor.ts +172 -0
  99. package/src/global_variable_builder/fee_provider.ts +75 -0
  100. package/src/global_variable_builder/global_builder.ts +26 -63
  101. package/src/global_variable_builder/index.ts +3 -1
  102. package/src/index.ts +5 -4
  103. package/src/publisher/config.ts +157 -45
  104. package/src/publisher/index.ts +3 -0
  105. package/src/publisher/l1_tx_failed_store/factory.ts +32 -0
  106. package/src/publisher/l1_tx_failed_store/failed_tx_store.ts +57 -0
  107. package/src/publisher/l1_tx_failed_store/file_store_failed_tx_store.ts +46 -0
  108. package/src/publisher/l1_tx_failed_store/index.ts +3 -0
  109. package/src/publisher/sequencer-bundle-simulator.ts +254 -0
  110. package/src/publisher/sequencer-publisher-factory.ts +39 -10
  111. package/src/publisher/sequencer-publisher-metrics.ts +17 -69
  112. package/src/publisher/sequencer-publisher.ts +611 -521
  113. package/src/sequencer/README.md +152 -450
  114. package/src/sequencer/automine/README.md +46 -0
  115. package/src/sequencer/automine/automine_factory.ts +145 -0
  116. package/src/sequencer/automine/automine_sequencer.ts +592 -0
  117. package/src/sequencer/chain_state_overrides.ts +162 -0
  118. package/src/sequencer/checkpoint_proposal_job.ts +1138 -230
  119. package/src/sequencer/checkpoint_proposal_job_metrics.ts +128 -0
  120. package/src/sequencer/checkpoint_voter.ts +31 -17
  121. package/src/sequencer/events.ts +50 -2
  122. package/src/sequencer/index.ts +2 -2
  123. package/src/sequencer/metrics.ts +168 -151
  124. package/src/sequencer/sequencer.ts +535 -162
  125. package/src/sequencer/timetable.ts +70 -57
  126. package/src/sequencer/types.ts +1 -1
  127. package/src/test/index.ts +3 -6
  128. package/src/test/mock_checkpoint_builder.ts +149 -73
  129. package/src/test/utils.ts +78 -30
  130. package/dest/sequencer/block_builder.d.ts +0 -26
  131. package/dest/sequencer/block_builder.d.ts.map +0 -1
  132. package/dest/sequencer/block_builder.js +0 -129
  133. package/dest/sequencer/checkpoint_builder.d.ts +0 -63
  134. package/dest/sequencer/checkpoint_builder.d.ts.map +0 -1
  135. package/dest/sequencer/checkpoint_builder.js +0 -131
  136. package/dest/tx_validator/nullifier_cache.d.ts +0 -14
  137. package/dest/tx_validator/nullifier_cache.d.ts.map +0 -1
  138. package/dest/tx_validator/nullifier_cache.js +0 -24
  139. package/dest/tx_validator/tx_validator_factory.d.ts +0 -18
  140. package/dest/tx_validator/tx_validator_factory.d.ts.map +0 -1
  141. package/dest/tx_validator/tx_validator_factory.js +0 -53
  142. package/src/sequencer/block_builder.ts +0 -217
  143. package/src/sequencer/checkpoint_builder.ts +0 -217
  144. package/src/tx_validator/nullifier_cache.ts +0 -30
  145. package/src/tx_validator/tx_validator_factory.ts +0 -133
@@ -11,14 +11,13 @@ import {
11
11
  type TelemetryClient,
12
12
  type Tracer,
13
13
  type UpDownCounter,
14
- ValueType,
14
+ createUpDownCounterWithDefault,
15
15
  } from '@aztec/telemetry-client';
16
16
 
17
17
  import { type Hex, formatUnits } from 'viem';
18
18
 
19
19
  import type { SequencerState } from './utils.js';
20
20
 
21
- // TODO(palla/mbps): Review all metrics and add any missing ones per checkpoint
22
21
  export class SequencerMetrics {
23
22
  public readonly tracer: Tracer;
24
23
  private meter: Meter;
@@ -27,6 +26,7 @@ export class SequencerMetrics {
27
26
  private blockBuildDuration: Histogram;
28
27
  private blockBuildManaPerSecond: Gauge;
29
28
  private stateTransitionBufferDuration: Histogram;
29
+ private stateDuration: Histogram;
30
30
 
31
31
  // these are gauges because for individual sequencers building a block is not something that happens often enough to warrant a histogram
32
32
  private timeToCollectAttestations: Gauge;
@@ -40,17 +40,24 @@ export class SequencerMetrics {
40
40
  private filledSlots: UpDownCounter;
41
41
 
42
42
  private blockProposalFailed: UpDownCounter;
43
- private blockProposalSuccess: UpDownCounter;
44
- private blockProposalPrecheckFailed: UpDownCounter;
43
+ private checkpointProposalSuccess: UpDownCounter;
44
+ private checkpointPrecheckFailed: UpDownCounter;
45
+ private checkpointProposalFailed: UpDownCounter;
45
46
  private checkpointSuccess: UpDownCounter;
46
47
  private slashingAttempts: UpDownCounter;
47
- private blockAttestationDelay: Histogram;
48
+ private pipelineDepth: Gauge;
49
+ private pipelineDiscards: UpDownCounter;
50
+ private pipelineParentCheckpointMismatches: UpDownCounter;
48
51
 
49
52
  // Fisherman fee analysis metrics
50
53
  private fishermanWouldBeIncluded: UpDownCounter;
51
54
  private fishermanTimeBeforeBlock: Histogram;
52
55
  private fishermanPendingBlobTxCount: Histogram;
53
56
  private fishermanIncludedBlobTxCount: Histogram;
57
+ private fishermanPendingBlobCount: Histogram;
58
+ private fishermanIncludedBlobCount: Histogram;
59
+ private fishermanBlockBlobsFull: UpDownCounter;
60
+ private fishermanMaxBlobCapacity: Histogram;
54
61
  private fishermanCalculatedPriorityFee: Histogram;
55
62
  private fishermanPriorityFeeDelta: Histogram;
56
63
  private fishermanEstimatedCost: Histogram;
@@ -58,6 +65,10 @@ export class SequencerMetrics {
58
65
  private fishermanMinedBlobTxPriorityFee: Histogram;
59
66
  private fishermanMinedBlobTxTotalCost: Histogram;
60
67
 
68
+ private blockInterBlockTime: Histogram;
69
+ private lastBlockBuiltTimestamp?: number;
70
+ private lastBlockBuiltSlot?: SlotNumber;
71
+
61
72
  private lastSeenSlot?: SlotNumber;
62
73
 
63
74
  constructor(
@@ -68,191 +79,138 @@ export class SequencerMetrics {
68
79
  this.meter = client.getMeter(name);
69
80
  this.tracer = client.getTracer(name);
70
81
 
71
- this.blockCounter = this.meter.createUpDownCounter(Metrics.SEQUENCER_BLOCK_COUNT);
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,
82
+ this.blockCounter = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_BLOCK_COUNT, {
83
+ [Attributes.STATUS]: ['failed', 'built'],
77
84
  });
78
85
 
79
- this.blockBuildManaPerSecond = this.meter.createGauge(Metrics.SEQUENCER_BLOCK_BUILD_MANA_PER_SECOND, {
80
- unit: 'mana/s',
81
- description: 'Mana per second when building a block',
82
- valueType: ValueType.INT,
83
- });
86
+ this.blockBuildDuration = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_DURATION);
84
87
 
85
- this.stateTransitionBufferDuration = this.meter.createHistogram(
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
- );
88
+ this.blockBuildManaPerSecond = this.meter.createGauge(Metrics.SEQUENCER_BLOCK_BUILD_MANA_PER_SECOND);
94
89
 
95
- this.blockAttestationDelay = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_ATTESTATION_DELAY, {
96
- unit: 'ms',
97
- description: 'The time difference between block proposal and minimal attestation count reached,',
98
- valueType: ValueType.INT,
99
- });
90
+ this.blockInterBlockTime = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_INTER_BLOCK_TIME);
100
91
 
101
- // Init gauges and counters
102
- this.blockCounter.add(0, {
103
- [Attributes.STATUS]: 'failed',
104
- });
105
- this.blockCounter.add(0, {
106
- [Attributes.STATUS]: 'built',
107
- });
92
+ this.stateTransitionBufferDuration = this.meter.createHistogram(Metrics.SEQUENCER_STATE_TRANSITION_BUFFER_DURATION);
108
93
 
109
- this.rewards = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_REWARDS, {
110
- valueType: ValueType.DOUBLE,
111
- description: 'The rewards earned',
112
- });
94
+ this.stateDuration = this.meter.createHistogram(Metrics.SEQUENCER_STATE_DURATION);
113
95
 
114
- this.slots = this.meter.createUpDownCounter(Metrics.SEQUENCER_SLOT_COUNT, {
115
- valueType: ValueType.INT,
116
- description: 'The number of slots this sequencer was selected for',
117
- });
96
+ this.rewards = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_SLOT_REWARDS);
97
+
98
+ this.slots = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_SLOT_COUNT);
118
99
 
119
100
  /**
120
101
  * NOTE: we do not track missed slots as a separate metric. That would be difficult to determine
121
102
  * Instead, use a computed metric, `slots - filledSlots` to get the number of slots a sequencer has missed.
122
103
  */
123
- this.filledSlots = this.meter.createUpDownCounter(Metrics.SEQUENCER_FILLED_SLOT_COUNT, {
124
- valueType: ValueType.INT,
125
- description: 'The number of slots this sequencer has filled',
126
- });
104
+ this.filledSlots = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_FILLED_SLOT_COUNT);
127
105
 
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
- });
106
+ this.timeToCollectAttestations = this.meter.createGauge(Metrics.SEQUENCER_COLLECT_ATTESTATIONS_DURATION);
133
107
 
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
- );
108
+ this.allowanceToCollectAttestations = this.meter.createGauge(Metrics.SEQUENCER_COLLECT_ATTESTATIONS_TIME_ALLOWANCE);
142
109
 
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
- });
110
+ this.requiredAttestions = this.meter.createGauge(Metrics.SEQUENCER_REQUIRED_ATTESTATIONS_COUNT);
147
111
 
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
- });
112
+ this.collectedAttestions = this.meter.createGauge(Metrics.SEQUENCER_COLLECTED_ATTESTATIONS_COUNT);
152
113
 
153
- this.blockProposalFailed = this.meter.createUpDownCounter(Metrics.SEQUENCER_BLOCK_PROPOSAL_FAILED_COUNT, {
154
- valueType: ValueType.INT,
155
- description: 'The number of times block proposal failed (including validation builds)',
156
- });
114
+ this.blockProposalFailed = createUpDownCounterWithDefault(
115
+ this.meter,
116
+ Metrics.SEQUENCER_BLOCK_PROPOSAL_FAILED_COUNT,
117
+ );
157
118
 
158
- this.blockProposalSuccess = this.meter.createUpDownCounter(Metrics.SEQUENCER_BLOCK_PROPOSAL_SUCCESS_COUNT, {
159
- valueType: ValueType.INT,
160
- description: 'The number of times block proposal succeeded (including validation builds)',
161
- });
119
+ this.checkpointProposalSuccess = createUpDownCounterWithDefault(
120
+ this.meter,
121
+ Metrics.SEQUENCER_CHECKPOINT_PROPOSAL_SUCCESS_COUNT,
122
+ );
162
123
 
163
- this.checkpointSuccess = this.meter.createUpDownCounter(Metrics.SEQUENCER_CHECKPOINT_SUCCESS_COUNT, {
164
- valueType: ValueType.INT,
165
- description: 'The number of times checkpoint publishing succeeded',
166
- });
124
+ this.checkpointSuccess = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_CHECKPOINT_SUCCESS_COUNT);
167
125
 
168
- this.blockProposalPrecheckFailed = this.meter.createUpDownCounter(
169
- Metrics.SEQUENCER_BLOCK_PROPOSAL_PRECHECK_FAILED_COUNT,
126
+ this.checkpointPrecheckFailed = createUpDownCounterWithDefault(
127
+ this.meter,
128
+ Metrics.SEQUENCER_CHECKPOINT_PRECHECK_FAILED_COUNT,
170
129
  {
171
- valueType: ValueType.INT,
172
- description: 'The number of times block proposal pre-build checks failed',
130
+ [Attributes.ERROR_TYPE]: [
131
+ 'slot_already_taken',
132
+ 'rollup_contract_check_failed',
133
+ 'slot_mismatch',
134
+ 'block_number_mismatch',
135
+ ],
173
136
  },
174
137
  );
175
138
 
176
- this.slashingAttempts = this.meter.createUpDownCounter(Metrics.SEQUENCER_SLASHING_ATTEMPTS_COUNT, {
177
- valueType: ValueType.INT,
178
- description: 'The number of slashing action attempts',
179
- });
139
+ this.checkpointProposalFailed = createUpDownCounterWithDefault(
140
+ this.meter,
141
+ Metrics.SEQUENCER_CHECKPOINT_PROPOSAL_FAILED_COUNT,
142
+ );
180
143
 
181
- // Fisherman fee analysis metrics
182
- this.fishermanWouldBeIncluded = this.meter.createUpDownCounter(Metrics.FISHERMAN_FEE_ANALYSIS_WOULD_BE_INCLUDED, {
183
- valueType: ValueType.INT,
184
- description: 'Whether the transaction would have been included in the block',
185
- });
144
+ this.slashingAttempts = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_SLASHING_ATTEMPTS_COUNT);
186
145
 
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
- });
146
+ this.pipelineDepth = this.meter.createGauge(Metrics.SEQUENCER_PIPELINE_DEPTH);
147
+ this.pipelineDiscards = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_PIPELINE_DISCARDS_COUNT);
148
+ this.pipelineParentCheckpointMismatches = createUpDownCounterWithDefault(
149
+ this.meter,
150
+ Metrics.SEQUENCER_PIPELINE_PARENT_CHECKPOINT_MISMATCH_COUNT,
151
+ {
152
+ [Attributes.ERROR_TYPE]: [
153
+ 'archiver-sync-timeout',
154
+ 'parent-not-on-l1',
155
+ 'parent-hash-mismatch',
156
+ 'parent-invalid-attestations',
157
+ 'unexpected-parent-appeared',
158
+ ],
159
+ },
160
+ );
161
+ this.pipelineDepth.record(0);
192
162
 
193
- this.fishermanPendingBlobTxCount = this.meter.createHistogram(
194
- Metrics.FISHERMAN_FEE_ANALYSIS_PENDING_BLOB_TX_COUNT,
163
+ // Fisherman fee analysis metrics
164
+ this.fishermanWouldBeIncluded = createUpDownCounterWithDefault(
165
+ this.meter,
166
+ Metrics.FISHERMAN_FEE_ANALYSIS_WOULD_BE_INCLUDED,
195
167
  {
196
- description: 'Number of blob transactions seen in the pending block',
197
- valueType: ValueType.INT,
168
+ [Attributes.OK]: [true, false],
169
+ [Attributes.BLOCK_FULL]: ['true', 'false'],
198
170
  },
199
171
  );
200
172
 
173
+ this.fishermanTimeBeforeBlock = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_TIME_BEFORE_BLOCK);
174
+
175
+ this.fishermanPendingBlobTxCount = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_PENDING_BLOB_TX_COUNT);
176
+
201
177
  this.fishermanIncludedBlobTxCount = this.meter.createHistogram(
202
178
  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
179
  );
208
180
 
209
181
  this.fishermanCalculatedPriorityFee = this.meter.createHistogram(
210
182
  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
183
  );
217
184
 
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
- });
185
+ this.fishermanPriorityFeeDelta = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_PRIORITY_FEE_DELTA);
223
186
 
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
- });
187
+ this.fishermanEstimatedCost = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_ESTIMATED_COST);
229
188
 
230
189
  this.fishermanEstimatedOverpayment = this.meter.createHistogram(
231
190
  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
191
  );
238
192
 
239
193
  this.fishermanMinedBlobTxPriorityFee = this.meter.createHistogram(
240
194
  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
195
  );
247
196
 
248
197
  this.fishermanMinedBlobTxTotalCost = this.meter.createHistogram(
249
198
  Metrics.FISHERMAN_FEE_ANALYSIS_MINED_BLOB_TX_TOTAL_COST,
199
+ );
200
+
201
+ this.fishermanPendingBlobCount = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_PENDING_BLOB_COUNT);
202
+
203
+ this.fishermanIncludedBlobCount = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_INCLUDED_BLOB_COUNT);
204
+
205
+ this.fishermanBlockBlobsFull = createUpDownCounterWithDefault(
206
+ this.meter,
207
+ Metrics.FISHERMAN_FEE_ANALYSIS_BLOCK_BLOBS_FULL,
250
208
  {
251
- unit: 'eth',
252
- description: 'Total cost in ETH for blob transactions in mined blocks',
253
- valueType: ValueType.DOUBLE,
209
+ [Attributes.OK]: [true, false],
254
210
  },
255
211
  );
212
+
213
+ this.fishermanMaxBlobCapacity = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_MAX_BLOB_CAPACITY);
256
214
  }
257
215
 
258
216
  public recordRequiredAttestations(requiredAttestationsCount: number, allowanceMs: number) {
@@ -264,21 +222,25 @@ export class SequencerMetrics {
264
222
  this.timeToCollectAttestations.record(0);
265
223
  }
266
224
 
267
- public recordBlockAttestationDelay(duration: number) {
268
- this.blockAttestationDelay.record(duration);
269
- }
270
-
271
225
  public recordCollectedAttestations(count: number, durationMs: number) {
272
226
  this.collectedAttestions.record(count);
273
227
  this.timeToCollectAttestations.record(Math.ceil(durationMs));
274
228
  }
275
229
 
276
- recordBuiltBlock(buildDurationMs: number, totalMana: number) {
230
+ recordBuiltBlock(buildDurationMs: number, totalMana: number, slot: SlotNumber) {
277
231
  this.blockCounter.add(1, {
278
232
  [Attributes.STATUS]: 'built',
279
233
  });
280
234
  this.blockBuildDuration.record(Math.ceil(buildDurationMs));
281
235
  this.blockBuildManaPerSecond.record(Math.ceil((totalMana * 1000) / buildDurationMs));
236
+
237
+ // Only record inter-block time between blocks built within the same slot.
238
+ const now = Date.now();
239
+ if (this.lastBlockBuiltTimestamp !== undefined && this.lastBlockBuiltSlot === slot) {
240
+ this.blockInterBlockTime.record(now - this.lastBlockBuiltTimestamp);
241
+ }
242
+ this.lastBlockBuiltTimestamp = now;
243
+ this.lastBlockBuiltSlot = slot;
282
244
  }
283
245
 
284
246
  recordFailedBlock() {
@@ -293,6 +255,26 @@ export class SequencerMetrics {
293
255
  });
294
256
  }
295
257
 
258
+ recordStateDuration(durationMs: number, state: SequencerState) {
259
+ this.stateDuration.record(Math.ceil(durationMs), {
260
+ [Attributes.SEQUENCER_STATE]: state,
261
+ });
262
+ }
263
+
264
+ recordPipelineDepth(depth: number) {
265
+ this.pipelineDepth.record(depth);
266
+ }
267
+
268
+ recordPipelineDiscard(count = 1) {
269
+ this.pipelineDiscards.add(count);
270
+ }
271
+
272
+ recordPipelineParentCheckpointMismatch(reason: string) {
273
+ this.pipelineParentCheckpointMismatches.add(1, {
274
+ [Attributes.ERROR_TYPE]: reason,
275
+ });
276
+ }
277
+
296
278
  incOpenSlot(slot: SlotNumber, proposer: string) {
297
279
  // sequencer went through the loop a second time. Noop
298
280
  if (slot === this.lastSeenSlot) {
@@ -335,13 +317,19 @@ export class SequencerMetrics {
335
317
  });
336
318
  }
337
319
 
338
- recordBlockProposalSuccess() {
339
- this.blockProposalSuccess.add(1);
320
+ recordCheckpointProposalSuccess() {
321
+ this.checkpointProposalSuccess.add(1);
340
322
  }
341
323
 
342
- recordBlockProposalPrecheckFailed(checkType: string) {
343
- this.blockProposalPrecheckFailed.add(1, {
344
- [Attributes.ERROR_TYPE]: checkType,
324
+ recordCheckpointPrecheckFailed(
325
+ checkType: 'slot_already_taken' | 'rollup_contract_check_failed' | 'slot_mismatch' | 'block_number_mismatch',
326
+ ) {
327
+ this.checkpointPrecheckFailed.add(1, { [Attributes.ERROR_TYPE]: checkType });
328
+ }
329
+
330
+ recordCheckpointProposalFailed(reason?: string) {
331
+ this.checkpointProposalFailed.add(1, {
332
+ ...(reason && { [Attributes.ERROR_TYPE]: reason }),
345
333
  });
346
334
  }
347
335
 
@@ -371,10 +359,12 @@ export class SequencerMetrics {
371
359
 
372
360
  // Record pending block snapshot data (once per strategy for comparison)
373
361
  this.fishermanPendingBlobTxCount.record(analysis.pendingSnapshot.pendingBlobTxCount, strategyAttributes);
362
+ this.fishermanPendingBlobCount.record(analysis.pendingSnapshot.pendingBlobCount, strategyAttributes);
374
363
 
375
364
  // Record mined block data if available
376
365
  if (analysis.minedBlock) {
377
366
  this.fishermanIncludedBlobTxCount.record(analysis.minedBlock.includedBlobTxCount, strategyAttributes);
367
+ this.fishermanIncludedBlobCount.record(analysis.minedBlock.includedBlobCount, strategyAttributes);
378
368
 
379
369
  // Record actual fees from blob transactions in the mined block
380
370
  for (const blobTx of analysis.minedBlock.includedBlobTxs) {
@@ -408,13 +398,28 @@ export class SequencerMetrics {
408
398
  if (analysis.analysis) {
409
399
  this.fishermanTimeBeforeBlock.record(Math.ceil(analysis.analysis.timeBeforeBlockMs), strategyAttributes);
410
400
 
401
+ // Record whether the block reached 100% blob capacity
402
+ if (analysis.analysis.blockBlobsFull) {
403
+ this.fishermanBlockBlobsFull.add(1, { ...strategyAttributes, [Attributes.OK]: true });
404
+ } else {
405
+ this.fishermanBlockBlobsFull.add(1, { ...strategyAttributes, [Attributes.OK]: false });
406
+ }
407
+
408
+ // Record the max blob capacity for this block
409
+ this.fishermanMaxBlobCapacity.record(analysis.analysis.maxBlobCapacity, strategyAttributes);
410
+
411
411
  // Record strategy-specific inclusion result
412
412
  if (strategyResult.wouldBeIncluded !== undefined) {
413
+ const inclusionAttributes = {
414
+ ...strategyAttributes,
415
+ [Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false',
416
+ };
417
+
413
418
  if (strategyResult.wouldBeIncluded) {
414
- this.fishermanWouldBeIncluded.add(1, { ...strategyAttributes, [Attributes.OK]: true });
419
+ this.fishermanWouldBeIncluded.add(1, { ...inclusionAttributes, [Attributes.OK]: true });
415
420
  } else {
416
421
  this.fishermanWouldBeIncluded.add(1, {
417
- ...strategyAttributes,
422
+ ...inclusionAttributes,
418
423
  [Attributes.OK]: false,
419
424
  ...(strategyResult.exclusionReason && { [Attributes.ERROR_TYPE]: strategyResult.exclusionReason }),
420
425
  });
@@ -424,17 +429,29 @@ export class SequencerMetrics {
424
429
  // Record strategy-specific priority fee delta
425
430
  if (strategyResult.priorityFeeDelta !== undefined) {
426
431
  const priorityFeeDeltaGwei = Number(strategyResult.priorityFeeDelta) / 1e9;
427
- this.fishermanPriorityFeeDelta.record(priorityFeeDeltaGwei, strategyAttributes);
432
+ const deltaAttributes = {
433
+ ...strategyAttributes,
434
+ [Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false',
435
+ };
436
+ this.fishermanPriorityFeeDelta.record(priorityFeeDeltaGwei, deltaAttributes);
428
437
  }
429
438
 
430
439
  // Record estimated cost if available
431
440
  if (strategyResult.estimatedCostEth !== undefined) {
432
- this.fishermanEstimatedCost.record(strategyResult.estimatedCostEth, strategyAttributes);
441
+ const costAttributes = {
442
+ ...strategyAttributes,
443
+ [Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false',
444
+ };
445
+ this.fishermanEstimatedCost.record(strategyResult.estimatedCostEth, costAttributes);
433
446
  }
434
447
 
435
448
  // Record estimated overpayment if available
436
449
  if (strategyResult.estimatedOverpaymentEth !== undefined) {
437
- this.fishermanEstimatedOverpayment.record(strategyResult.estimatedOverpaymentEth, strategyAttributes);
450
+ const overpaymentAttributes = {
451
+ ...strategyAttributes,
452
+ [Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false',
453
+ };
454
+ this.fishermanEstimatedOverpayment.record(strategyResult.estimatedOverpaymentEth, overpaymentAttributes);
438
455
  }
439
456
  }
440
457
  }