@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
@@ -1,6 +1,5 @@
1
- import { Attributes, Metrics, ValueType } from '@aztec/telemetry-client';
1
+ import { Attributes, Metrics, createUpDownCounterWithDefault } from '@aztec/telemetry-client';
2
2
  import { formatUnits } from 'viem';
3
- // TODO(palla/mbps): Review all metrics and add any missing ones per checkpoint
4
3
  export class SequencerMetrics {
5
4
  rollup;
6
5
  tracer;
@@ -9,6 +8,7 @@ export class SequencerMetrics {
9
8
  blockBuildDuration;
10
9
  blockBuildManaPerSecond;
11
10
  stateTransitionBufferDuration;
11
+ stateDuration;
12
12
  // these are gauges because for individual sequencers building a block is not something that happens often enough to warrant a histogram
13
13
  timeToCollectAttestations;
14
14
  allowanceToCollectAttestations;
@@ -18,156 +18,112 @@ export class SequencerMetrics {
18
18
  slots;
19
19
  filledSlots;
20
20
  blockProposalFailed;
21
- blockProposalSuccess;
22
- blockProposalPrecheckFailed;
21
+ checkpointProposalSuccess;
22
+ checkpointPrecheckFailed;
23
+ checkpointProposalFailed;
23
24
  checkpointSuccess;
24
25
  slashingAttempts;
25
- blockAttestationDelay;
26
+ pipelineDepth;
27
+ pipelineDiscards;
28
+ pipelineParentCheckpointMismatches;
26
29
  // Fisherman fee analysis metrics
27
30
  fishermanWouldBeIncluded;
28
31
  fishermanTimeBeforeBlock;
29
32
  fishermanPendingBlobTxCount;
30
33
  fishermanIncludedBlobTxCount;
34
+ fishermanPendingBlobCount;
35
+ fishermanIncludedBlobCount;
36
+ fishermanBlockBlobsFull;
37
+ fishermanMaxBlobCapacity;
31
38
  fishermanCalculatedPriorityFee;
32
39
  fishermanPriorityFeeDelta;
33
40
  fishermanEstimatedCost;
34
41
  fishermanEstimatedOverpayment;
35
42
  fishermanMinedBlobTxPriorityFee;
36
43
  fishermanMinedBlobTxTotalCost;
44
+ blockInterBlockTime;
45
+ lastBlockBuiltTimestamp;
46
+ lastBlockBuiltSlot;
37
47
  lastSeenSlot;
38
48
  constructor(client, rollup, name = 'Sequencer'){
39
49
  this.rollup = rollup;
40
50
  this.meter = client.getMeter(name);
41
51
  this.tracer = client.getTracer(name);
42
- this.blockCounter = this.meter.createUpDownCounter(Metrics.SEQUENCER_BLOCK_COUNT);
43
- this.blockBuildDuration = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_DURATION, {
44
- unit: 'ms',
45
- description: 'Duration to build a block',
46
- valueType: ValueType.INT
47
- });
48
- this.blockBuildManaPerSecond = this.meter.createGauge(Metrics.SEQUENCER_BLOCK_BUILD_MANA_PER_SECOND, {
49
- unit: 'mana/s',
50
- description: 'Mana per second when building a block',
51
- valueType: ValueType.INT
52
- });
53
- this.stateTransitionBufferDuration = this.meter.createHistogram(Metrics.SEQUENCER_STATE_TRANSITION_BUFFER_DURATION, {
54
- unit: 'ms',
55
- description: 'The time difference between when the sequencer needed to transition to a new state and when it actually did.',
56
- valueType: ValueType.INT
57
- });
58
- this.blockAttestationDelay = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_ATTESTATION_DELAY, {
59
- unit: 'ms',
60
- description: 'The time difference between block proposal and minimal attestation count reached,',
61
- valueType: ValueType.INT
62
- });
63
- // Init gauges and counters
64
- this.blockCounter.add(0, {
65
- [Attributes.STATUS]: 'failed'
66
- });
67
- this.blockCounter.add(0, {
68
- [Attributes.STATUS]: 'built'
69
- });
70
- this.rewards = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_REWARDS, {
71
- valueType: ValueType.DOUBLE,
72
- description: 'The rewards earned'
73
- });
74
- this.slots = this.meter.createUpDownCounter(Metrics.SEQUENCER_SLOT_COUNT, {
75
- valueType: ValueType.INT,
76
- description: 'The number of slots this sequencer was selected for'
77
- });
52
+ this.blockCounter = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_BLOCK_COUNT, {
53
+ [Attributes.STATUS]: [
54
+ 'failed',
55
+ 'built'
56
+ ]
57
+ });
58
+ this.blockBuildDuration = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_DURATION);
59
+ this.blockBuildManaPerSecond = this.meter.createGauge(Metrics.SEQUENCER_BLOCK_BUILD_MANA_PER_SECOND);
60
+ this.blockInterBlockTime = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_INTER_BLOCK_TIME);
61
+ this.stateTransitionBufferDuration = this.meter.createHistogram(Metrics.SEQUENCER_STATE_TRANSITION_BUFFER_DURATION);
62
+ this.stateDuration = this.meter.createHistogram(Metrics.SEQUENCER_STATE_DURATION);
63
+ this.rewards = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_SLOT_REWARDS);
64
+ this.slots = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_SLOT_COUNT);
78
65
  /**
79
66
  * NOTE: we do not track missed slots as a separate metric. That would be difficult to determine
80
67
  * Instead, use a computed metric, `slots - filledSlots` to get the number of slots a sequencer has missed.
81
- */ this.filledSlots = this.meter.createUpDownCounter(Metrics.SEQUENCER_FILLED_SLOT_COUNT, {
82
- valueType: ValueType.INT,
83
- description: 'The number of slots this sequencer has filled'
84
- });
85
- this.timeToCollectAttestations = this.meter.createGauge(Metrics.SEQUENCER_COLLECT_ATTESTATIONS_DURATION, {
86
- description: 'The time spent collecting attestations from committee members',
87
- unit: 'ms',
88
- valueType: ValueType.INT
89
- });
90
- this.allowanceToCollectAttestations = this.meter.createGauge(Metrics.SEQUENCER_COLLECT_ATTESTATIONS_TIME_ALLOWANCE, {
91
- description: 'Maximum amount of time to collect attestations',
92
- unit: 'ms',
93
- valueType: ValueType.INT
94
- });
95
- this.requiredAttestions = this.meter.createGauge(Metrics.SEQUENCER_REQUIRED_ATTESTATIONS_COUNT, {
96
- valueType: ValueType.INT,
97
- description: 'The minimum number of attestations required to publish a block'
98
- });
99
- this.collectedAttestions = this.meter.createGauge(Metrics.SEQUENCER_COLLECTED_ATTESTATIONS_COUNT, {
100
- valueType: ValueType.INT,
101
- description: 'The minimum number of attestations required to publish a block'
102
- });
103
- this.blockProposalFailed = this.meter.createUpDownCounter(Metrics.SEQUENCER_BLOCK_PROPOSAL_FAILED_COUNT, {
104
- valueType: ValueType.INT,
105
- description: 'The number of times block proposal failed (including validation builds)'
106
- });
107
- this.blockProposalSuccess = this.meter.createUpDownCounter(Metrics.SEQUENCER_BLOCK_PROPOSAL_SUCCESS_COUNT, {
108
- valueType: ValueType.INT,
109
- description: 'The number of times block proposal succeeded (including validation builds)'
110
- });
111
- this.checkpointSuccess = this.meter.createUpDownCounter(Metrics.SEQUENCER_CHECKPOINT_SUCCESS_COUNT, {
112
- valueType: ValueType.INT,
113
- description: 'The number of times checkpoint publishing succeeded'
114
- });
115
- this.blockProposalPrecheckFailed = this.meter.createUpDownCounter(Metrics.SEQUENCER_BLOCK_PROPOSAL_PRECHECK_FAILED_COUNT, {
116
- valueType: ValueType.INT,
117
- description: 'The number of times block proposal pre-build checks failed'
118
- });
119
- this.slashingAttempts = this.meter.createUpDownCounter(Metrics.SEQUENCER_SLASHING_ATTEMPTS_COUNT, {
120
- valueType: ValueType.INT,
121
- description: 'The number of slashing action attempts'
122
- });
68
+ */ this.filledSlots = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_FILLED_SLOT_COUNT);
69
+ this.timeToCollectAttestations = this.meter.createGauge(Metrics.SEQUENCER_COLLECT_ATTESTATIONS_DURATION);
70
+ this.allowanceToCollectAttestations = this.meter.createGauge(Metrics.SEQUENCER_COLLECT_ATTESTATIONS_TIME_ALLOWANCE);
71
+ this.requiredAttestions = this.meter.createGauge(Metrics.SEQUENCER_REQUIRED_ATTESTATIONS_COUNT);
72
+ this.collectedAttestions = this.meter.createGauge(Metrics.SEQUENCER_COLLECTED_ATTESTATIONS_COUNT);
73
+ this.blockProposalFailed = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_BLOCK_PROPOSAL_FAILED_COUNT);
74
+ this.checkpointProposalSuccess = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_CHECKPOINT_PROPOSAL_SUCCESS_COUNT);
75
+ this.checkpointSuccess = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_CHECKPOINT_SUCCESS_COUNT);
76
+ this.checkpointPrecheckFailed = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_CHECKPOINT_PRECHECK_FAILED_COUNT, {
77
+ [Attributes.ERROR_TYPE]: [
78
+ 'slot_already_taken',
79
+ 'rollup_contract_check_failed',
80
+ 'slot_mismatch',
81
+ 'block_number_mismatch'
82
+ ]
83
+ });
84
+ this.checkpointProposalFailed = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_CHECKPOINT_PROPOSAL_FAILED_COUNT);
85
+ this.slashingAttempts = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_SLASHING_ATTEMPTS_COUNT);
86
+ this.pipelineDepth = this.meter.createGauge(Metrics.SEQUENCER_PIPELINE_DEPTH);
87
+ this.pipelineDiscards = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_PIPELINE_DISCARDS_COUNT);
88
+ this.pipelineParentCheckpointMismatches = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_PIPELINE_PARENT_CHECKPOINT_MISMATCH_COUNT, {
89
+ [Attributes.ERROR_TYPE]: [
90
+ 'archiver-sync-timeout',
91
+ 'parent-not-on-l1',
92
+ 'parent-hash-mismatch',
93
+ 'parent-invalid-attestations',
94
+ 'unexpected-parent-appeared'
95
+ ]
96
+ });
97
+ this.pipelineDepth.record(0);
123
98
  // Fisherman fee analysis metrics
124
- this.fishermanWouldBeIncluded = this.meter.createUpDownCounter(Metrics.FISHERMAN_FEE_ANALYSIS_WOULD_BE_INCLUDED, {
125
- valueType: ValueType.INT,
126
- description: 'Whether the transaction would have been included in the block'
127
- });
128
- this.fishermanTimeBeforeBlock = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_TIME_BEFORE_BLOCK, {
129
- unit: 'ms',
130
- description: 'Time in ms between fee analysis and block being mined',
131
- valueType: ValueType.INT
132
- });
133
- this.fishermanPendingBlobTxCount = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_PENDING_BLOB_TX_COUNT, {
134
- description: 'Number of blob transactions seen in the pending block',
135
- valueType: ValueType.INT
136
- });
137
- this.fishermanIncludedBlobTxCount = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_INCLUDED_BLOB_TX_COUNT, {
138
- description: 'Number of blob transactions that got included in the mined block',
139
- valueType: ValueType.INT
140
- });
141
- this.fishermanCalculatedPriorityFee = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_CALCULATED_PRIORITY_FEE, {
142
- unit: 'gwei',
143
- description: 'Priority fee calculated by each strategy',
144
- valueType: ValueType.DOUBLE
145
- });
146
- this.fishermanPriorityFeeDelta = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_PRIORITY_FEE_DELTA, {
147
- unit: 'gwei',
148
- description: 'Difference between our priority fee and minimum included priority fee',
149
- valueType: ValueType.DOUBLE
150
- });
151
- this.fishermanEstimatedCost = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_ESTIMATED_COST, {
152
- unit: 'eth',
153
- description: 'Estimated total cost in ETH for the transaction with this strategy',
154
- valueType: ValueType.DOUBLE
155
- });
156
- this.fishermanEstimatedOverpayment = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_ESTIMATED_OVERPAYMENT, {
157
- unit: 'eth',
158
- description: 'Estimated overpayment in ETH vs minimum required for inclusion',
159
- valueType: ValueType.DOUBLE
160
- });
161
- this.fishermanMinedBlobTxPriorityFee = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_MINED_BLOB_TX_PRIORITY_FEE, {
162
- unit: 'gwei',
163
- description: 'Priority fee per gas for blob transactions in mined blocks',
164
- valueType: ValueType.DOUBLE
165
- });
166
- this.fishermanMinedBlobTxTotalCost = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_MINED_BLOB_TX_TOTAL_COST, {
167
- unit: 'eth',
168
- description: 'Total cost in ETH for blob transactions in mined blocks',
169
- valueType: ValueType.DOUBLE
170
- });
99
+ this.fishermanWouldBeIncluded = createUpDownCounterWithDefault(this.meter, Metrics.FISHERMAN_FEE_ANALYSIS_WOULD_BE_INCLUDED, {
100
+ [Attributes.OK]: [
101
+ true,
102
+ false
103
+ ],
104
+ [Attributes.BLOCK_FULL]: [
105
+ 'true',
106
+ 'false'
107
+ ]
108
+ });
109
+ this.fishermanTimeBeforeBlock = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_TIME_BEFORE_BLOCK);
110
+ this.fishermanPendingBlobTxCount = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_PENDING_BLOB_TX_COUNT);
111
+ this.fishermanIncludedBlobTxCount = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_INCLUDED_BLOB_TX_COUNT);
112
+ this.fishermanCalculatedPriorityFee = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_CALCULATED_PRIORITY_FEE);
113
+ this.fishermanPriorityFeeDelta = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_PRIORITY_FEE_DELTA);
114
+ this.fishermanEstimatedCost = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_ESTIMATED_COST);
115
+ this.fishermanEstimatedOverpayment = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_ESTIMATED_OVERPAYMENT);
116
+ this.fishermanMinedBlobTxPriorityFee = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_MINED_BLOB_TX_PRIORITY_FEE);
117
+ this.fishermanMinedBlobTxTotalCost = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_MINED_BLOB_TX_TOTAL_COST);
118
+ this.fishermanPendingBlobCount = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_PENDING_BLOB_COUNT);
119
+ this.fishermanIncludedBlobCount = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_INCLUDED_BLOB_COUNT);
120
+ this.fishermanBlockBlobsFull = createUpDownCounterWithDefault(this.meter, Metrics.FISHERMAN_FEE_ANALYSIS_BLOCK_BLOBS_FULL, {
121
+ [Attributes.OK]: [
122
+ true,
123
+ false
124
+ ]
125
+ });
126
+ this.fishermanMaxBlobCapacity = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_MAX_BLOB_CAPACITY);
171
127
  }
172
128
  recordRequiredAttestations(requiredAttestationsCount, allowanceMs) {
173
129
  this.requiredAttestions.record(requiredAttestationsCount);
@@ -176,19 +132,23 @@ export class SequencerMetrics {
176
132
  this.collectedAttestions.record(0);
177
133
  this.timeToCollectAttestations.record(0);
178
134
  }
179
- recordBlockAttestationDelay(duration) {
180
- this.blockAttestationDelay.record(duration);
181
- }
182
135
  recordCollectedAttestations(count, durationMs) {
183
136
  this.collectedAttestions.record(count);
184
137
  this.timeToCollectAttestations.record(Math.ceil(durationMs));
185
138
  }
186
- recordBuiltBlock(buildDurationMs, totalMana) {
139
+ recordBuiltBlock(buildDurationMs, totalMana, slot) {
187
140
  this.blockCounter.add(1, {
188
141
  [Attributes.STATUS]: 'built'
189
142
  });
190
143
  this.blockBuildDuration.record(Math.ceil(buildDurationMs));
191
144
  this.blockBuildManaPerSecond.record(Math.ceil(totalMana * 1000 / buildDurationMs));
145
+ // Only record inter-block time between blocks built within the same slot.
146
+ const now = Date.now();
147
+ if (this.lastBlockBuiltTimestamp !== undefined && this.lastBlockBuiltSlot === slot) {
148
+ this.blockInterBlockTime.record(now - this.lastBlockBuiltTimestamp);
149
+ }
150
+ this.lastBlockBuiltTimestamp = now;
151
+ this.lastBlockBuiltSlot = slot;
192
152
  }
193
153
  recordFailedBlock() {
194
154
  this.blockCounter.add(1, {
@@ -200,6 +160,22 @@ export class SequencerMetrics {
200
160
  [Attributes.SEQUENCER_STATE]: state
201
161
  });
202
162
  }
163
+ recordStateDuration(durationMs, state) {
164
+ this.stateDuration.record(Math.ceil(durationMs), {
165
+ [Attributes.SEQUENCER_STATE]: state
166
+ });
167
+ }
168
+ recordPipelineDepth(depth) {
169
+ this.pipelineDepth.record(depth);
170
+ }
171
+ recordPipelineDiscard(count = 1) {
172
+ this.pipelineDiscards.add(count);
173
+ }
174
+ recordPipelineParentCheckpointMismatch(reason) {
175
+ this.pipelineParentCheckpointMismatches.add(1, {
176
+ [Attributes.ERROR_TYPE]: reason
177
+ });
178
+ }
203
179
  incOpenSlot(slot, proposer) {
204
180
  // sequencer went through the loop a second time. Noop
205
181
  if (slot === this.lastSeenSlot) {
@@ -237,14 +213,21 @@ export class SequencerMetrics {
237
213
  }
238
214
  });
239
215
  }
240
- recordBlockProposalSuccess() {
241
- this.blockProposalSuccess.add(1);
216
+ recordCheckpointProposalSuccess() {
217
+ this.checkpointProposalSuccess.add(1);
242
218
  }
243
- recordBlockProposalPrecheckFailed(checkType) {
244
- this.blockProposalPrecheckFailed.add(1, {
219
+ recordCheckpointPrecheckFailed(checkType) {
220
+ this.checkpointPrecheckFailed.add(1, {
245
221
  [Attributes.ERROR_TYPE]: checkType
246
222
  });
247
223
  }
224
+ recordCheckpointProposalFailed(reason) {
225
+ this.checkpointProposalFailed.add(1, {
226
+ ...reason && {
227
+ [Attributes.ERROR_TYPE]: reason
228
+ }
229
+ });
230
+ }
248
231
  recordSlashingAttempt(actionCount) {
249
232
  this.slashingAttempts.add(actionCount);
250
233
  }
@@ -265,9 +248,11 @@ export class SequencerMetrics {
265
248
  };
266
249
  // Record pending block snapshot data (once per strategy for comparison)
267
250
  this.fishermanPendingBlobTxCount.record(analysis.pendingSnapshot.pendingBlobTxCount, strategyAttributes);
251
+ this.fishermanPendingBlobCount.record(analysis.pendingSnapshot.pendingBlobCount, strategyAttributes);
268
252
  // Record mined block data if available
269
253
  if (analysis.minedBlock) {
270
254
  this.fishermanIncludedBlobTxCount.record(analysis.minedBlock.includedBlobTxCount, strategyAttributes);
255
+ this.fishermanIncludedBlobCount.record(analysis.minedBlock.includedBlobCount, strategyAttributes);
271
256
  // Record actual fees from blob transactions in the mined block
272
257
  for (const blobTx of analysis.minedBlock.includedBlobTxs){
273
258
  // Record priority fee per gas in Gwei
@@ -292,16 +277,34 @@ export class SequencerMetrics {
292
277
  // Record analysis results if available
293
278
  if (analysis.analysis) {
294
279
  this.fishermanTimeBeforeBlock.record(Math.ceil(analysis.analysis.timeBeforeBlockMs), strategyAttributes);
280
+ // Record whether the block reached 100% blob capacity
281
+ if (analysis.analysis.blockBlobsFull) {
282
+ this.fishermanBlockBlobsFull.add(1, {
283
+ ...strategyAttributes,
284
+ [Attributes.OK]: true
285
+ });
286
+ } else {
287
+ this.fishermanBlockBlobsFull.add(1, {
288
+ ...strategyAttributes,
289
+ [Attributes.OK]: false
290
+ });
291
+ }
292
+ // Record the max blob capacity for this block
293
+ this.fishermanMaxBlobCapacity.record(analysis.analysis.maxBlobCapacity, strategyAttributes);
295
294
  // Record strategy-specific inclusion result
296
295
  if (strategyResult.wouldBeIncluded !== undefined) {
296
+ const inclusionAttributes = {
297
+ ...strategyAttributes,
298
+ [Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false'
299
+ };
297
300
  if (strategyResult.wouldBeIncluded) {
298
301
  this.fishermanWouldBeIncluded.add(1, {
299
- ...strategyAttributes,
302
+ ...inclusionAttributes,
300
303
  [Attributes.OK]: true
301
304
  });
302
305
  } else {
303
306
  this.fishermanWouldBeIncluded.add(1, {
304
- ...strategyAttributes,
307
+ ...inclusionAttributes,
305
308
  [Attributes.OK]: false,
306
309
  ...strategyResult.exclusionReason && {
307
310
  [Attributes.ERROR_TYPE]: strategyResult.exclusionReason
@@ -312,15 +315,27 @@ export class SequencerMetrics {
312
315
  // Record strategy-specific priority fee delta
313
316
  if (strategyResult.priorityFeeDelta !== undefined) {
314
317
  const priorityFeeDeltaGwei = Number(strategyResult.priorityFeeDelta) / 1e9;
315
- this.fishermanPriorityFeeDelta.record(priorityFeeDeltaGwei, strategyAttributes);
318
+ const deltaAttributes = {
319
+ ...strategyAttributes,
320
+ [Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false'
321
+ };
322
+ this.fishermanPriorityFeeDelta.record(priorityFeeDeltaGwei, deltaAttributes);
316
323
  }
317
324
  // Record estimated cost if available
318
325
  if (strategyResult.estimatedCostEth !== undefined) {
319
- this.fishermanEstimatedCost.record(strategyResult.estimatedCostEth, strategyAttributes);
326
+ const costAttributes = {
327
+ ...strategyAttributes,
328
+ [Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false'
329
+ };
330
+ this.fishermanEstimatedCost.record(strategyResult.estimatedCostEth, costAttributes);
320
331
  }
321
332
  // Record estimated overpayment if available
322
333
  if (strategyResult.estimatedOverpaymentEth !== undefined) {
323
- this.fishermanEstimatedOverpayment.record(strategyResult.estimatedOverpaymentEth, strategyAttributes);
334
+ const overpaymentAttributes = {
335
+ ...strategyAttributes,
336
+ [Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false'
337
+ };
338
+ this.fishermanEstimatedOverpayment.record(strategyResult.estimatedOverpaymentEth, overpaymentAttributes);
324
339
  }
325
340
  }
326
341
  }