@lodestar/validator 1.35.0-dev.f80d2d52da → 1.35.0-dev.fcf8d024ea

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 (173) hide show
  1. package/lib/buckets.d.ts.map +1 -0
  2. package/lib/defaults.d.ts.map +1 -0
  3. package/lib/genesis.d.ts.map +1 -0
  4. package/lib/index.d.ts +7 -7
  5. package/lib/index.d.ts.map +1 -0
  6. package/lib/index.js +5 -5
  7. package/lib/index.js.map +1 -1
  8. package/lib/metrics.d.ts.map +1 -0
  9. package/lib/metrics.js +14 -14
  10. package/lib/metrics.js.map +1 -1
  11. package/lib/repositories/index.d.ts.map +1 -0
  12. package/lib/repositories/metaDataRepository.d.ts.map +1 -0
  13. package/lib/repositories/metaDataRepository.js +4 -3
  14. package/lib/repositories/metaDataRepository.js.map +1 -1
  15. package/lib/services/attestation.d.ts.map +1 -0
  16. package/lib/services/attestation.js +77 -60
  17. package/lib/services/attestation.js.map +1 -1
  18. package/lib/services/attestationDuties.d.ts.map +1 -0
  19. package/lib/services/attestationDuties.js +105 -98
  20. package/lib/services/attestationDuties.js.map +1 -1
  21. package/lib/services/block.d.ts.map +1 -0
  22. package/lib/services/block.js +64 -56
  23. package/lib/services/block.js.map +1 -1
  24. package/lib/services/blockDuties.d.ts +2 -2
  25. package/lib/services/blockDuties.d.ts.map +1 -0
  26. package/lib/services/blockDuties.js +35 -26
  27. package/lib/services/blockDuties.js.map +1 -1
  28. package/lib/services/chainHeaderTracker.d.ts.map +1 -0
  29. package/lib/services/chainHeaderTracker.js +30 -27
  30. package/lib/services/chainHeaderTracker.js.map +1 -1
  31. package/lib/services/doppelgangerService.d.ts.map +1 -0
  32. package/lib/services/doppelgangerService.js +52 -45
  33. package/lib/services/doppelgangerService.js.map +1 -1
  34. package/lib/services/emitter.d.ts +1 -1
  35. package/lib/services/emitter.d.ts.map +1 -0
  36. package/lib/services/externalSignerSync.d.ts.map +1 -0
  37. package/lib/services/externalSignerSync.js.map +1 -1
  38. package/lib/services/indices.d.ts.map +1 -0
  39. package/lib/services/indices.js +8 -5
  40. package/lib/services/indices.js.map +1 -1
  41. package/lib/services/prepareBeaconProposer.d.ts.map +1 -0
  42. package/lib/services/prepareBeaconProposer.js.map +1 -1
  43. package/lib/services/syncCommittee.d.ts.map +1 -0
  44. package/lib/services/syncCommittee.js +80 -61
  45. package/lib/services/syncCommittee.js.map +1 -1
  46. package/lib/services/syncCommitteeDuties.d.ts.map +1 -0
  47. package/lib/services/syncCommitteeDuties.js +28 -23
  48. package/lib/services/syncCommitteeDuties.js.map +1 -1
  49. package/lib/services/syncingStatusTracker.d.ts.map +1 -0
  50. package/lib/services/syncingStatusTracker.js +32 -27
  51. package/lib/services/syncingStatusTracker.js.map +1 -1
  52. package/lib/services/utils.d.ts.map +1 -0
  53. package/lib/services/validatorStore.d.ts.map +1 -0
  54. package/lib/services/validatorStore.js +9 -3
  55. package/lib/services/validatorStore.js.map +1 -1
  56. package/lib/slashingProtection/attestation/attestationByTargetRepository.d.ts.map +1 -0
  57. package/lib/slashingProtection/attestation/attestationByTargetRepository.js +7 -3
  58. package/lib/slashingProtection/attestation/attestationByTargetRepository.js.map +1 -1
  59. package/lib/slashingProtection/attestation/attestationLowerBoundRepository.d.ts.map +1 -0
  60. package/lib/slashingProtection/attestation/attestationLowerBoundRepository.js +5 -3
  61. package/lib/slashingProtection/attestation/attestationLowerBoundRepository.js.map +1 -1
  62. package/lib/slashingProtection/attestation/errors.d.ts.map +1 -0
  63. package/lib/slashingProtection/attestation/index.d.ts.map +1 -0
  64. package/lib/slashingProtection/attestation/index.js +3 -0
  65. package/lib/slashingProtection/attestation/index.js.map +1 -1
  66. package/lib/slashingProtection/block/blockBySlotRepository.d.ts.map +1 -0
  67. package/lib/slashingProtection/block/blockBySlotRepository.js +7 -3
  68. package/lib/slashingProtection/block/blockBySlotRepository.js.map +1 -1
  69. package/lib/slashingProtection/block/errors.d.ts.map +1 -0
  70. package/lib/slashingProtection/block/index.d.ts.map +1 -0
  71. package/lib/slashingProtection/block/index.js +1 -0
  72. package/lib/slashingProtection/block/index.js.map +1 -1
  73. package/lib/slashingProtection/index.d.ts +1 -1
  74. package/lib/slashingProtection/index.d.ts.map +1 -0
  75. package/lib/slashingProtection/index.js +3 -0
  76. package/lib/slashingProtection/index.js.map +1 -1
  77. package/lib/slashingProtection/interchange/errors.d.ts.map +1 -0
  78. package/lib/slashingProtection/interchange/formats/completeV4.d.ts.map +1 -0
  79. package/lib/slashingProtection/interchange/formats/index.d.ts.map +1 -0
  80. package/lib/slashingProtection/interchange/formats/v5.d.ts.map +1 -0
  81. package/lib/slashingProtection/interchange/index.d.ts.map +1 -0
  82. package/lib/slashingProtection/interchange/parseInterchange.d.ts.map +1 -0
  83. package/lib/slashingProtection/interchange/serializeInterchange.d.ts.map +1 -0
  84. package/lib/slashingProtection/interchange/types.d.ts.map +1 -0
  85. package/lib/slashingProtection/interface.d.ts.map +1 -0
  86. package/lib/slashingProtection/minMaxSurround/distanceStoreRepository.d.ts.map +1 -0
  87. package/lib/slashingProtection/minMaxSurround/distanceStoreRepository.js +8 -0
  88. package/lib/slashingProtection/minMaxSurround/distanceStoreRepository.js.map +1 -1
  89. package/lib/slashingProtection/minMaxSurround/errors.d.ts.map +1 -0
  90. package/lib/slashingProtection/minMaxSurround/index.d.ts.map +1 -0
  91. package/lib/slashingProtection/minMaxSurround/interface.d.ts.map +1 -0
  92. package/lib/slashingProtection/minMaxSurround/minMaxSurround.d.ts.map +1 -0
  93. package/lib/slashingProtection/minMaxSurround/minMaxSurround.js +2 -0
  94. package/lib/slashingProtection/minMaxSurround/minMaxSurround.js.map +1 -1
  95. package/lib/slashingProtection/types.d.ts.map +1 -0
  96. package/lib/slashingProtection/utils.d.ts +1 -1
  97. package/lib/slashingProtection/utils.d.ts.map +1 -0
  98. package/lib/types.d.ts.map +1 -0
  99. package/lib/util/batch.d.ts.map +1 -0
  100. package/lib/util/clock.d.ts +3 -0
  101. package/lib/util/clock.d.ts.map +1 -0
  102. package/lib/util/clock.js +9 -1
  103. package/lib/util/clock.js.map +1 -1
  104. package/lib/util/difference.d.ts.map +1 -0
  105. package/lib/util/externalSignerClient.d.ts.map +1 -0
  106. package/lib/util/format.d.ts.map +1 -0
  107. package/lib/util/index.d.ts.map +1 -0
  108. package/lib/util/logger.d.ts.map +1 -0
  109. package/lib/util/params.d.ts.map +1 -0
  110. package/lib/util/params.js +18 -2
  111. package/lib/util/params.js.map +1 -1
  112. package/lib/util/url.d.ts.map +1 -0
  113. package/lib/validator.d.ts.map +1 -0
  114. package/lib/validator.js +15 -0
  115. package/lib/validator.js.map +1 -1
  116. package/package.json +19 -16
  117. package/src/buckets.ts +30 -0
  118. package/src/defaults.ts +8 -0
  119. package/src/genesis.ts +19 -0
  120. package/src/index.ts +22 -0
  121. package/src/metrics.ts +417 -0
  122. package/src/repositories/index.ts +1 -0
  123. package/src/repositories/metaDataRepository.ts +42 -0
  124. package/src/services/attestation.ts +362 -0
  125. package/src/services/attestationDuties.ts +406 -0
  126. package/src/services/block.ts +261 -0
  127. package/src/services/blockDuties.ts +217 -0
  128. package/src/services/chainHeaderTracker.ts +89 -0
  129. package/src/services/doppelgangerService.ts +286 -0
  130. package/src/services/emitter.ts +43 -0
  131. package/src/services/externalSignerSync.ts +81 -0
  132. package/src/services/indices.ts +165 -0
  133. package/src/services/prepareBeaconProposer.ts +119 -0
  134. package/src/services/syncCommittee.ts +338 -0
  135. package/src/services/syncCommitteeDuties.ts +337 -0
  136. package/src/services/syncingStatusTracker.ts +74 -0
  137. package/src/services/utils.ts +58 -0
  138. package/src/services/validatorStore.ts +830 -0
  139. package/src/slashingProtection/attestation/attestationByTargetRepository.ts +77 -0
  140. package/src/slashingProtection/attestation/attestationLowerBoundRepository.ts +44 -0
  141. package/src/slashingProtection/attestation/errors.ts +66 -0
  142. package/src/slashingProtection/attestation/index.ts +171 -0
  143. package/src/slashingProtection/block/blockBySlotRepository.ts +78 -0
  144. package/src/slashingProtection/block/errors.ts +28 -0
  145. package/src/slashingProtection/block/index.ts +94 -0
  146. package/src/slashingProtection/index.ts +95 -0
  147. package/src/slashingProtection/interchange/errors.ts +15 -0
  148. package/src/slashingProtection/interchange/formats/completeV4.ts +125 -0
  149. package/src/slashingProtection/interchange/formats/index.ts +7 -0
  150. package/src/slashingProtection/interchange/formats/v5.ts +120 -0
  151. package/src/slashingProtection/interchange/index.ts +5 -0
  152. package/src/slashingProtection/interchange/parseInterchange.ts +55 -0
  153. package/src/slashingProtection/interchange/serializeInterchange.ts +35 -0
  154. package/src/slashingProtection/interchange/types.ts +18 -0
  155. package/src/slashingProtection/interface.ts +28 -0
  156. package/src/slashingProtection/minMaxSurround/distanceStoreRepository.ts +57 -0
  157. package/src/slashingProtection/minMaxSurround/errors.ts +27 -0
  158. package/src/slashingProtection/minMaxSurround/index.ts +4 -0
  159. package/src/slashingProtection/minMaxSurround/interface.ts +23 -0
  160. package/src/slashingProtection/minMaxSurround/minMaxSurround.ts +104 -0
  161. package/src/slashingProtection/types.ts +12 -0
  162. package/src/slashingProtection/utils.ts +42 -0
  163. package/src/types.ts +31 -0
  164. package/src/util/batch.ts +15 -0
  165. package/src/util/clock.ts +170 -0
  166. package/src/util/difference.ts +10 -0
  167. package/src/util/externalSignerClient.ts +277 -0
  168. package/src/util/format.ts +3 -0
  169. package/src/util/index.ts +6 -0
  170. package/src/util/logger.ts +51 -0
  171. package/src/util/params.ts +320 -0
  172. package/src/util/url.ts +16 -0
  173. package/src/validator.ts +418 -0
package/src/index.ts ADDED
@@ -0,0 +1,22 @@
1
+ export {waitForGenesis} from "./genesis.js";
2
+ export {type Metrics, getMetrics} from "./metrics.js";
3
+ export * from "./repositories/index.js";
4
+ export type {
5
+ ProposerConfig,
6
+ Signer,
7
+ SignerLocal,
8
+ SignerRemote,
9
+ ValidatorProposerConfig,
10
+ } from "./services/validatorStore.js";
11
+ export {MAX_BUILDER_BOOST_FACTOR, SignerType, ValidatorStore, defaultOptions} from "./services/validatorStore.js";
12
+ export * from "./slashingProtection/index.js";
13
+ // Types
14
+ export type {ProcessShutdownCallback} from "./types.js";
15
+ // Remote signer client
16
+ export {
17
+ SignableMessageType,
18
+ externalSignerGetKeys,
19
+ externalSignerPostSignature,
20
+ externalSignerUpCheck,
21
+ } from "./util/externalSignerClient.js";
22
+ export {Validator, type ValidatorOptions} from "./validator.js";
package/src/metrics.ts ADDED
@@ -0,0 +1,417 @@
1
+ import {routes} from "@lodestar/api";
2
+ import {MetricsRegisterExtra} from "@lodestar/utils";
3
+
4
+ export enum MessageSource {
5
+ forward = "forward",
6
+ publish = "publish",
7
+ }
8
+
9
+ export enum BeaconHealth {
10
+ READY = 0,
11
+ SYNCING = 1,
12
+ ERROR = 2,
13
+ }
14
+
15
+ export type Metrics = ReturnType<typeof getMetrics>;
16
+
17
+ export type LodestarGitData = {
18
+ /** "0.16.0 developer/feature-1 ac99f2b5" */
19
+ version: string;
20
+ /** "4f816b16dfde718e2d74f95f2c8292596138c248" */
21
+ commit: string;
22
+ /** "holesky" */
23
+ network: string;
24
+ };
25
+
26
+ /**
27
+ * A collection of metrics used by the validator client
28
+ */
29
+ export function getMetrics(register: MetricsRegisterExtra, gitData: LodestarGitData) {
30
+ // Using function style instead of class to prevent having to re-declare all MetricsPrometheus types.
31
+
32
+ // Track version, same as https://github.com/ChainSafe/lodestar/blob/6df28de64f12ea90b341b219229a47c8a25c9343/packages/lodestar/src/metrics/metrics/lodestar.ts#L17
33
+ register
34
+ .gauge<LodestarGitData>({
35
+ name: "lodestar_version",
36
+ help: "Lodestar version",
37
+ labelNames: Object.keys(gitData) as [keyof LodestarGitData],
38
+ })
39
+ .set(gitData, 1);
40
+
41
+ return {
42
+ defaultConfiguration: register.gauge<{
43
+ builderSelection: routes.validator.BuilderSelection;
44
+ broadcastValidation: routes.beacon.BroadcastValidation;
45
+ }>({
46
+ name: "vc_default_configuration",
47
+ help: "Default validator configuration",
48
+ labelNames: ["builderSelection", "broadcastValidation"],
49
+ }),
50
+
51
+ // Attestation journey:
52
+ // - Wait for block or ATTESTATION_DUE_BPS, call prepare attestation
53
+ // - Get attestation, sign, call publish
54
+ // - Wait AGGREGATE_DUE_BPS, call prepare aggregate
55
+ // - Get aggregate, sign, call publish
56
+
57
+ attesterStepCallProduceAttestation: register.histogram({
58
+ name: "vc_attester_step_call_produce_attestation_seconds",
59
+ help: "Time between ATTESTATION_DUE_BPS of slot and call produce attestation",
60
+ // Attester flow can start early if block is imported before ATTESTATION_DUE_BPS of the slot
61
+ // This measure is critical so we need very good resolution around the 0 second mark
62
+ buckets: [-3, -1, 0, 1, 2, 3, 6, 12],
63
+ }),
64
+ attesterStepCallPublishAttestation: register.histogram({
65
+ name: "vc_attester_step_call_publish_attestation_seconds",
66
+ help: "Time between ATTESTATION_DUE_BPS of slot and call publish attestation",
67
+ buckets: [-3, -1, 0, 1, 2, 3, 6, 12],
68
+ }),
69
+
70
+ attesterStepCallProduceAggregate: register.histogram({
71
+ name: "vc_attester_step_call_produce_aggregate_seconds",
72
+ help: "Time between AGGREGATE_DUE_BPS of slot and call produce aggregate",
73
+ // Aggregate production starts at AGGREGATE_DUE_BPS the earliest.
74
+ // Track values close to 0 (expected) in greater resolution, values over 12 overflow into the next slot.
75
+ buckets: [0.5, 1, 2, 3, 6, 12],
76
+ }),
77
+ attesterStepCallPublishAggregate: register.histogram({
78
+ name: "vc_attester_step_call_publish_aggregate_seconds",
79
+ help: "Time between AGGREGATE_DUE_BPS of slot and call publish aggregate",
80
+ buckets: [0.5, 1, 2, 3, 6, 12],
81
+ }),
82
+
83
+ syncCommitteeStepCallProduceMessage: register.histogram({
84
+ name: "vc_sync_committee_step_call_produce_message_seconds",
85
+ help: "Time between SYNC_MESSAGE_DUE_BPS of slot and call produce message",
86
+ // Max wait time is SYNC_MESSAGE_DUE_BPS of slot
87
+ buckets: [0.5, 1, 2, 3, 6, 12],
88
+ }),
89
+ syncCommitteeStepCallPublishMessage: register.histogram({
90
+ name: "vc_sync_committee_step_call_publish_message_seconds",
91
+ help: "Time between SYNC_MESSAGE_DUE_BPS of slot and call publish message",
92
+ buckets: [0.5, 1, 2, 3, 6, 12],
93
+ }),
94
+
95
+ syncCommitteeStepCallProduceAggregate: register.histogram({
96
+ name: "vc_sync_committee_step_call_produce_aggregate_seconds",
97
+ help: "Time between CONTRIBUTION_DUE_BPS of slot and call produce aggregate",
98
+ // Min wait time is CONTRIBUTION_DUE_BPS of slot
99
+ buckets: [0.5, 1, 2, 3, 6, 12],
100
+ }),
101
+ syncCommitteeStepCallPublishAggregate: register.histogram({
102
+ name: "vc_sync_committee_step_call_publish_aggregate_seconds",
103
+ help: "Time between CONTRIBUTION_DUE_BPS of slot and call publish aggregate",
104
+ buckets: [0.5, 1, 2, 3, 6, 12],
105
+ }),
106
+
107
+ // Min wait time it 0. CallProduceBlock step is a bit redundant since it must be 0, but let's check
108
+ proposerStepCallProduceBlock: register.histogram({
109
+ name: "vc_proposer_step_call_produce_block_seconds",
110
+ help: "Time between start of slot and call produce block",
111
+ buckets: [0.5, 1, 2, 3, 6, 8],
112
+ }),
113
+ proposerStepCallPublishBlock: register.histogram({
114
+ name: "vc_proposer_step_call_publish_block_seconds",
115
+ help: "Time between start of slot and call publish block",
116
+ buckets: [0.5, 1, 2, 3, 6, 8],
117
+ }),
118
+
119
+ // AttestationService
120
+
121
+ publishedAttestations: register.gauge({
122
+ name: "vc_published_attestations_total",
123
+ help: "Total published attestations",
124
+ }),
125
+
126
+ publishedAggregates: register.gauge({
127
+ name: "vc_published_aggregates_total",
128
+ help: "Total published aggregates",
129
+ }),
130
+
131
+ numParticipantsInAggregate: register.histogram({
132
+ name: "vc_attestation_service_participants_in_aggregate_total",
133
+ help: "Number of attestations in the published AggregatedAttestation",
134
+ buckets: [1, 25, 50, 100, 250, 400, 500, 600],
135
+ }),
136
+
137
+ attestaterError: register.gauge<{error: "produce" | "sign" | "publish"}>({
138
+ name: "vc_attestation_service_errors",
139
+ help: "Total errors in AttestationService",
140
+ labelNames: ["error"],
141
+ }),
142
+
143
+ // AttestationDutiesService
144
+
145
+ attesterDutiesCount: register.gauge({
146
+ name: "vc_attester_duties_count",
147
+ help: "Current count of duties in AttestationDutiesService",
148
+ }),
149
+
150
+ attesterDutiesEpochCount: register.gauge({
151
+ name: "vc_attester_duties_epoch_count",
152
+ help: "Current count of epoch duties in AttestationDutiesService",
153
+ }),
154
+
155
+ attesterDutiesReorg: register.gauge({
156
+ name: "vc_attestation_duties_reorg_total",
157
+ help: "Total count of instances the attester duties dependent root changed",
158
+ }),
159
+
160
+ attesterDutiesNextSlot: register.gauge({
161
+ // Metric is used by Rocket Pool dashboard (18391) to determine seconds until next attestation.
162
+ // It works without requiring any modification to the dashboard as the metric name is the
163
+ // same as Lighthouse uses for this.
164
+ name: "vc_attestation_duty_slot",
165
+ help: "Slot of next scheduled attestation duty",
166
+ }),
167
+
168
+ // BlockProposingService
169
+
170
+ blocksProduced: register.gauge({
171
+ name: "vc_block_produced_total",
172
+ help: "Total count of blocks produced",
173
+ }),
174
+
175
+ blocksPublished: register.gauge({
176
+ name: "vc_block_published_total",
177
+ help: "Total count of blocks published",
178
+ }),
179
+
180
+ blockProposingErrors: register.gauge<{error: "produce" | "publish"}>({
181
+ name: "vc_block_proposing_errors_total",
182
+ help: "Total count of errors producing or publishing a block",
183
+ labelNames: ["error"],
184
+ }),
185
+
186
+ // BlockDutiesService
187
+
188
+ proposerDutiesEpochCount: register.gauge({
189
+ name: "vc_proposer_duties_epoch_count",
190
+ help: "Current count of epoch duties in BlockDutiesService",
191
+ }),
192
+
193
+ proposerDutiesReorg: register.gauge({
194
+ name: "vc_proposer_duties_reorg_total",
195
+ help: "Total count of instances the proposer duties dependent root changed",
196
+ }),
197
+
198
+ newProposalDutiesDetected: register.gauge({
199
+ name: "vc_new_proposal_duties_detected_total",
200
+ help: "Total count of times new proposal duties were detected",
201
+ }),
202
+
203
+ // IndicesService
204
+
205
+ indices: register.gauge({
206
+ name: "vc_indices_count",
207
+ help: "Current count of indices in IndicesService",
208
+ }),
209
+
210
+ discoveredIndices: register.gauge({
211
+ name: "vc_discovered_indices_total",
212
+ help: "Total count of validator indices discovered",
213
+ }),
214
+
215
+ // SyncCommitteeService
216
+
217
+ publishedSyncCommitteeMessage: register.gauge({
218
+ name: "vc_published_sync_committee_message_total",
219
+ help: "Total published SyncCommitteeMessage",
220
+ }),
221
+
222
+ publishedSyncCommitteeContribution: register.gauge({
223
+ name: "vc_published_sync_committee_contribution_total",
224
+ help: "Total published SyncCommitteeContribution",
225
+ }),
226
+
227
+ // SyncCommitteeDutiesService
228
+
229
+ syncCommitteeDutiesCount: register.gauge({
230
+ name: "vc_sync_committee_duties_count",
231
+ help: "Current count of duties in SyncCommitteeDutiesService",
232
+ }),
233
+
234
+ syncCommitteeDutiesEpochCount: register.gauge({
235
+ name: "vc_sync_committee_duties_epoch_count",
236
+ help: "Current count of epoch duties in SyncCommitteeDutiesService",
237
+ }),
238
+
239
+ syncCommitteeDutiesReorg: register.gauge({
240
+ name: "vc_sync_committee_duties_reorg_total",
241
+ help: "Total count of instances the sync committee duties dependent root changed",
242
+ }),
243
+
244
+ // ValidatorStore
245
+
246
+ signers: register.gauge({
247
+ name: "vc_signers_count",
248
+ help: "Total count of instances the sync committee duties dependent root changed",
249
+ }),
250
+
251
+ localSignTime: register.histogram({
252
+ name: "vc_local_sign_time_seconds",
253
+ help: "Histogram of sign time for any signature with local signer",
254
+ // When using a local keystores, signing time is ~ 1ms
255
+ buckets: [0.0001, 0.001, 0.01, 0.1],
256
+ }),
257
+
258
+ remoteSignTime: register.histogram({
259
+ name: "vc_remote_sign_time_seconds",
260
+ help: "Histogram of sign time for any signature with remote signer",
261
+ // When using a remote signer sign time can be ~ 50-500ms
262
+ buckets: [0.01, 0.1, 1, 5],
263
+ }),
264
+
265
+ remoteSignErrors: register.gauge({
266
+ name: "vc_remote_sign_errors_total",
267
+ help: "Total count of errors calling a remote signer",
268
+ }),
269
+
270
+ signError: register.gauge({
271
+ name: "vc_sign_errors_total",
272
+ help: "Total count of errors calling a signer",
273
+ }),
274
+
275
+ slashingProtectionBlockError: register.gauge({
276
+ name: "vc_slashing_protection_block_errors_total",
277
+ help: "Total count of errors on slashingProtection.checkAndInsertBlockProposal",
278
+ }),
279
+
280
+ slashingProtectionAttestationError: register.gauge({
281
+ name: "vc_slashing_protection_attestation_errors_total",
282
+ help: "Total count of errors on slashingProtection.checkAndInsertAttestation",
283
+ }),
284
+
285
+ // REST API client
286
+
287
+ beaconHealth: register.gauge({
288
+ name: "vc_beacon_health",
289
+ help: `Current health status of the beacon(s) the validator is connected to. ${renderEnumNumeric(BeaconHealth)}`,
290
+ }),
291
+
292
+ restApiClient: {
293
+ requestTime: register.histogram<{routeId: string}>({
294
+ name: "vc_rest_api_client_request_time_seconds",
295
+ help: "Histogram of REST API client request time by routeId",
296
+ labelNames: ["routeId"],
297
+ // Expected times are ~ 50-500ms, but in an overload NodeJS they can be greater
298
+ buckets: [0.01, 0.1, 1, 2, 5],
299
+ }),
300
+
301
+ streamTime: register.histogram<{routeId: string}>({
302
+ name: "vc_rest_api_client_stream_time_seconds",
303
+ help: "Histogram of REST API client streaming time by routeId",
304
+ labelNames: ["routeId"],
305
+ // Expected times are ~ 50-500ms, but in an overload NodeJS they can be greater
306
+ buckets: [0.01, 0.1, 1, 2, 5],
307
+ }),
308
+
309
+ requestErrors: register.gauge<{routeId: string; baseUrl: string}>({
310
+ name: "vc_rest_api_client_request_errors_total",
311
+ help: "Total count of errors on REST API client requests by routeId",
312
+ labelNames: ["routeId", "baseUrl"],
313
+ }),
314
+
315
+ requestToFallbacks: register.gauge<{routeId: string; baseUrl: string}>({
316
+ name: "vc_rest_api_client_request_to_fallbacks_total",
317
+ help: "Total count of requests to fallback URLs on REST API by routeId",
318
+ labelNames: ["routeId", "baseUrl"],
319
+ }),
320
+
321
+ urlsScore: register.gauge<{urlIndex: number; baseUrl: string}>({
322
+ name: "vc_rest_api_client_urls_score",
323
+ help: "Current score of REST API URLs by url index",
324
+ labelNames: ["urlIndex", "baseUrl"],
325
+ }),
326
+ },
327
+
328
+ keymanagerApiRest: {
329
+ responseTime: register.histogram<{operationId: string}>({
330
+ name: "vc_keymanager_api_rest_response_time_seconds",
331
+ help: "REST API time to fulfill a request by operationId",
332
+ labelNames: ["operationId"],
333
+ // Request times range between 1ms to 100ms in normal conditions. Can get to 1-5 seconds if overloaded
334
+ buckets: [0.01, 0.1, 1],
335
+ }),
336
+ requests: register.gauge<{operationId: string}>({
337
+ name: "vc_keymanager_api_rest_requests_total",
338
+ help: "REST API total count requests by operationId",
339
+ labelNames: ["operationId"],
340
+ }),
341
+ errors: register.gauge<{operationId: string}>({
342
+ name: "vc_keymanager_api_rest_errors_total",
343
+ help: "REST API total count of errors by operationId",
344
+ labelNames: ["operationId"],
345
+ }),
346
+ // Metrics for HttpActiveSocketsTracker, defined there
347
+ activeSockets: register.gauge({
348
+ name: "vc_keymanager_api_rest_active_sockets_count",
349
+ help: "REST API current count of active sockets",
350
+ }),
351
+ socketsBytesRead: register.gauge({
352
+ name: "vc_keymanager_api_rest_sockets_bytes_read_total",
353
+ help: "REST API total count of bytes read on all sockets",
354
+ }),
355
+ socketsBytesWritten: register.gauge({
356
+ name: "vc_keymanager_api_rest_sockets_bytes_written_total",
357
+ help: "REST API total count of bytes written on all sockets",
358
+ }),
359
+ },
360
+
361
+ db: {
362
+ dbReadReq: register.gauge<{bucket: string}>({
363
+ name: "vc_db_read_req_total",
364
+ help: "Total count of db read requests, may read 0 or more items",
365
+ labelNames: ["bucket"],
366
+ }),
367
+ dbReadItems: register.gauge<{bucket: string}>({
368
+ name: "vc_db_read_items_total",
369
+ help: "Total count of db read items, item = key | value | entry",
370
+ labelNames: ["bucket"],
371
+ }),
372
+ dbWriteReq: register.gauge<{bucket: string}>({
373
+ name: "vc_db_write_req_total",
374
+ help: "Total count of db write requests, may write 0 or more items",
375
+ labelNames: ["bucket"],
376
+ }),
377
+ dbWriteItems: register.gauge<{bucket: string}>({
378
+ name: "vc_db_write_items_total",
379
+ help: "Total count of db write items",
380
+ labelNames: ["bucket"],
381
+ }),
382
+ dbSizeTotal: register.gauge({
383
+ name: "vc_db_size_bytes_total",
384
+ help: "Approximate number of bytes of file system space used by db",
385
+ }),
386
+ dbApproximateSizeTime: register.histogram({
387
+ name: "vc_db_approximate_size_time_seconds",
388
+ help: "Time to approximate db size in seconds",
389
+ buckets: [0.0001, 0.001, 0.01, 0.1, 1],
390
+ }),
391
+ },
392
+
393
+ doppelganger: {
394
+ statusCount: register.gauge<{status: string}>({
395
+ name: "vc_doppelganger_validator_status_count",
396
+ help: "Count of validators per status",
397
+ labelNames: ["status"],
398
+ }),
399
+ epochsChecked: register.gauge({
400
+ name: "vc_doppelganger_epochs_checked_total",
401
+ help: "Total count of epochs checked",
402
+ }),
403
+ },
404
+ };
405
+ }
406
+
407
+ export function renderEnumNumeric(obj: Record<string, unknown>): string {
408
+ const out: string[] = [];
409
+
410
+ for (const [key, value] of Object.entries(obj)) {
411
+ if (typeof value === "number") {
412
+ out.push(`${key}=${value}`);
413
+ }
414
+ }
415
+
416
+ return out.join(", ");
417
+ }
@@ -0,0 +1 @@
1
+ export * from "./metaDataRepository.js";
@@ -0,0 +1,42 @@
1
+ import {DbReqOpts, encodeKey} from "@lodestar/db";
2
+ import {Root, UintNum64, ssz} from "@lodestar/types";
3
+ import {Bucket, getBucketNameByValue} from "../buckets.js";
4
+ import {LodestarValidatorDatabaseController} from "../types.js";
5
+
6
+ const GENESIS_VALIDATORS_ROOT = Buffer.from("GENESIS_VALIDATORS_ROOT");
7
+ const GENESIS_TIME = Buffer.from("GENESIS_TIME");
8
+
9
+ /**
10
+ * Store MetaData of validator.
11
+ */
12
+ export class MetaDataRepository {
13
+ protected bucket = Bucket.validator_metaData;
14
+
15
+ private readonly bucketId = getBucketNameByValue(this.bucket);
16
+ private readonly dbReqOpts: DbReqOpts = {bucketId: this.bucketId};
17
+
18
+ constructor(protected db: LodestarValidatorDatabaseController) {
19
+ this.dbReqOpts = {bucketId: this.bucketId};
20
+ }
21
+
22
+ async getGenesisValidatorsRoot(): Promise<Root | null> {
23
+ return this.db.get(this.encodeKey(GENESIS_VALIDATORS_ROOT), this.dbReqOpts);
24
+ }
25
+
26
+ async setGenesisValidatorsRoot(genesisValidatorsRoot: Root): Promise<void> {
27
+ await this.db.put(this.encodeKey(GENESIS_VALIDATORS_ROOT), genesisValidatorsRoot, this.dbReqOpts);
28
+ }
29
+
30
+ async getGenesisTime(): Promise<UintNum64 | null> {
31
+ const bytes = await this.db.get(this.encodeKey(GENESIS_TIME), this.dbReqOpts);
32
+ return bytes ? ssz.UintNum64.deserialize(bytes) : null;
33
+ }
34
+
35
+ async setGenesisTime(genesisTime: UintNum64): Promise<void> {
36
+ await this.db.put(this.encodeKey(GENESIS_TIME), ssz.UintNum64.serialize(genesisTime), this.dbReqOpts);
37
+ }
38
+
39
+ private encodeKey(key: Uint8Array): Uint8Array {
40
+ return encodeKey(this.bucket, key);
41
+ }
42
+ }