@lodestar/beacon-node 1.50.0-dev.db953a4f93 → 1.50.0-dev.dff4197219

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 (247) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +6 -1
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/index.d.ts.map +1 -1
  5. package/lib/api/impl/beacon/index.js +13 -0
  6. package/lib/api/impl/beacon/index.js.map +1 -1
  7. package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
  8. package/lib/api/impl/beacon/state/index.js +28 -6
  9. package/lib/api/impl/beacon/state/index.js.map +1 -1
  10. package/lib/api/impl/debug/index.d.ts.map +1 -1
  11. package/lib/api/impl/debug/index.js +26 -18
  12. package/lib/api/impl/debug/index.js.map +1 -1
  13. package/lib/api/impl/validator/index.d.ts +1 -0
  14. package/lib/api/impl/validator/index.d.ts.map +1 -1
  15. package/lib/api/impl/validator/index.js +23 -1
  16. package/lib/api/impl/validator/index.js.map +1 -1
  17. package/lib/chain/archiveStore/archiveStore.d.ts +5 -0
  18. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  19. package/lib/chain/archiveStore/archiveStore.js +14 -24
  20. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  21. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +2 -2
  22. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  23. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +5 -7
  24. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  25. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -1
  26. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
  27. package/lib/chain/archiveStore/historicalState/types.d.ts +2 -2
  28. package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
  29. package/lib/chain/archiveStore/historicalState/worker.js +1 -1
  30. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  31. package/lib/chain/archiveStore/interface.d.ts +1 -1
  32. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  33. package/lib/chain/archiveStore/utils/pruneHistory.d.ts +1 -1
  34. package/lib/chain/archiveStore/utils/pruneHistory.d.ts.map +1 -1
  35. package/lib/chain/archiveStore/utils/pruneHistory.js +2 -1
  36. package/lib/chain/archiveStore/utils/pruneHistory.js.map +1 -1
  37. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  38. package/lib/chain/blocks/importBlock.js +13 -6
  39. package/lib/chain/blocks/importBlock.js.map +1 -1
  40. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +2 -1
  41. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  42. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  43. package/lib/chain/blocks/verifyBlock.js +7 -7
  44. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  45. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts +2 -1
  46. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  47. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +5 -4
  48. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  49. package/lib/chain/chain.d.ts +9 -5
  50. package/lib/chain/chain.d.ts.map +1 -1
  51. package/lib/chain/chain.js +87 -33
  52. package/lib/chain/chain.js.map +1 -1
  53. package/lib/chain/emitter.d.ts +7 -1
  54. package/lib/chain/emitter.d.ts.map +1 -1
  55. package/lib/chain/emitter.js +5 -0
  56. package/lib/chain/emitter.js.map +1 -1
  57. package/lib/chain/errors/envelopeReconstructionError.d.ts +5 -0
  58. package/lib/chain/errors/envelopeReconstructionError.d.ts.map +1 -1
  59. package/lib/chain/errors/envelopeReconstructionError.js +2 -0
  60. package/lib/chain/errors/envelopeReconstructionError.js.map +1 -1
  61. package/lib/chain/errors/gossipValidation.d.ts +3 -1
  62. package/lib/chain/errors/gossipValidation.d.ts.map +1 -1
  63. package/lib/chain/errors/gossipValidation.js +2 -0
  64. package/lib/chain/errors/gossipValidation.js.map +1 -1
  65. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  66. package/lib/chain/forkChoice/index.js +2 -0
  67. package/lib/chain/forkChoice/index.js.map +1 -1
  68. package/lib/chain/interface.d.ts +3 -2
  69. package/lib/chain/interface.d.ts.map +1 -1
  70. package/lib/chain/opPools/aggregatedAttestationPool.d.ts +4 -2
  71. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  72. package/lib/chain/opPools/aggregatedAttestationPool.js +30 -8
  73. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  74. package/lib/chain/opPools/proposerPreferencesPool.d.ts +4 -4
  75. package/lib/chain/opPools/proposerPreferencesPool.d.ts.map +1 -1
  76. package/lib/chain/opPools/proposerPreferencesPool.js +14 -11
  77. package/lib/chain/opPools/proposerPreferencesPool.js.map +1 -1
  78. package/lib/chain/options.d.ts +2 -1
  79. package/lib/chain/options.d.ts.map +1 -1
  80. package/lib/chain/options.js +1 -1
  81. package/lib/chain/options.js.map +1 -1
  82. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  83. package/lib/chain/prepareNextSlot.js +5 -2
  84. package/lib/chain/prepareNextSlot.js.map +1 -1
  85. package/lib/chain/produceBlock/computeNewStateRoot.js +1 -1
  86. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  87. package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -1
  88. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  89. package/lib/chain/produceBlock/produceBlockBody.js +6 -2
  90. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  91. package/lib/chain/regen/regen.d.ts +2 -0
  92. package/lib/chain/regen/regen.d.ts.map +1 -1
  93. package/lib/chain/regen/regen.js +10 -4
  94. package/lib/chain/regen/regen.js.map +1 -1
  95. package/lib/chain/seenCache/seenGossipBlockInput.d.ts +7 -0
  96. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  97. package/lib/chain/seenCache/seenGossipBlockInput.js +21 -0
  98. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  99. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +9 -2
  100. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  101. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +23 -13
  102. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  103. package/lib/chain/shufflingCache.d.ts +18 -8
  104. package/lib/chain/shufflingCache.d.ts.map +1 -1
  105. package/lib/chain/shufflingCache.js +72 -18
  106. package/lib/chain/shufflingCache.js.map +1 -1
  107. package/lib/chain/validatorMonitor.d.ts +5 -1
  108. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  109. package/lib/chain/validatorMonitor.js +64 -54
  110. package/lib/chain/validatorMonitor.js.map +1 -1
  111. package/lib/db/beacon.d.ts +2 -0
  112. package/lib/db/beacon.d.ts.map +1 -1
  113. package/lib/db/beacon.js +3 -0
  114. package/lib/db/beacon.js.map +1 -1
  115. package/lib/db/buckets.d.ts +2 -1
  116. package/lib/db/buckets.d.ts.map +1 -1
  117. package/lib/db/buckets.js +1 -0
  118. package/lib/db/buckets.js.map +1 -1
  119. package/lib/db/interface.d.ts +2 -0
  120. package/lib/db/interface.d.ts.map +1 -1
  121. package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
  122. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  123. package/lib/db/repositories/earliestAvailableSlot.d.ts +11 -0
  124. package/lib/db/repositories/earliestAvailableSlot.d.ts.map +1 -0
  125. package/lib/db/repositories/earliestAvailableSlot.js +19 -0
  126. package/lib/db/repositories/earliestAvailableSlot.js.map +1 -0
  127. package/lib/execution/engine/disabled.d.ts +0 -2
  128. package/lib/execution/engine/disabled.d.ts.map +1 -1
  129. package/lib/execution/engine/disabled.js +0 -6
  130. package/lib/execution/engine/disabled.js.map +1 -1
  131. package/lib/execution/engine/http.d.ts +1 -3
  132. package/lib/execution/engine/http.d.ts.map +1 -1
  133. package/lib/execution/engine/http.js +2 -17
  134. package/lib/execution/engine/http.js.map +1 -1
  135. package/lib/execution/engine/interface.d.ts +2 -4
  136. package/lib/execution/engine/interface.d.ts.map +1 -1
  137. package/lib/execution/engine/mock.d.ts +0 -2
  138. package/lib/execution/engine/mock.d.ts.map +1 -1
  139. package/lib/execution/engine/mock.js +0 -8
  140. package/lib/execution/engine/mock.js.map +1 -1
  141. package/lib/execution/engine/types.d.ts +0 -8
  142. package/lib/execution/engine/types.d.ts.map +1 -1
  143. package/lib/execution/engine/types.js.map +1 -1
  144. package/lib/metrics/metrics/lodestar.d.ts +7 -0
  145. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  146. package/lib/metrics/metrics/lodestar.js +17 -0
  147. package/lib/metrics/metrics/lodestar.js.map +1 -1
  148. package/lib/metrics/metrics.d.ts +7 -3
  149. package/lib/metrics/metrics.d.ts.map +1 -1
  150. package/lib/metrics/metrics.js +4 -4
  151. package/lib/metrics/metrics.js.map +1 -1
  152. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  153. package/lib/network/processor/gossipHandlers.js +62 -63
  154. package/lib/network/processor/gossipHandlers.js.map +1 -1
  155. package/lib/network/processor/gossipValidatorFn.d.ts +7 -3
  156. package/lib/network/processor/gossipValidatorFn.d.ts.map +1 -1
  157. package/lib/network/processor/gossipValidatorFn.js +7 -3
  158. package/lib/network/processor/gossipValidatorFn.js.map +1 -1
  159. package/lib/network/processor/index.d.ts +9 -0
  160. package/lib/network/processor/index.d.ts.map +1 -1
  161. package/lib/network/processor/index.js +77 -10
  162. package/lib/network/processor/index.js.map +1 -1
  163. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +1 -1
  164. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
  165. package/lib/node/nodejs.d.ts +3 -1
  166. package/lib/node/nodejs.d.ts.map +1 -1
  167. package/lib/node/nodejs.js +27 -4
  168. package/lib/node/nodejs.js.map +1 -1
  169. package/lib/sync/range/batch.d.ts +11 -5
  170. package/lib/sync/range/batch.d.ts.map +1 -1
  171. package/lib/sync/range/batch.js +21 -17
  172. package/lib/sync/range/batch.js.map +1 -1
  173. package/lib/sync/range/chain.d.ts +4 -4
  174. package/lib/sync/range/chain.d.ts.map +1 -1
  175. package/lib/sync/range/chain.js +12 -6
  176. package/lib/sync/range/chain.js.map +1 -1
  177. package/lib/sync/range/range.d.ts.map +1 -1
  178. package/lib/sync/range/range.js +75 -29
  179. package/lib/sync/range/range.js.map +1 -1
  180. package/lib/sync/unknownBlock.d.ts +5 -2
  181. package/lib/sync/unknownBlock.d.ts.map +1 -1
  182. package/lib/sync/unknownBlock.js +49 -24
  183. package/lib/sync/unknownBlock.js.map +1 -1
  184. package/lib/sync/utils/downloadByRange.d.ts +38 -14
  185. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  186. package/lib/sync/utils/downloadByRange.js +84 -39
  187. package/lib/sync/utils/downloadByRange.js.map +1 -1
  188. package/lib/util/execution.d.ts +9 -11
  189. package/lib/util/execution.d.ts.map +1 -1
  190. package/lib/util/execution.js +5 -1
  191. package/lib/util/execution.js.map +1 -1
  192. package/package.json +17 -17
  193. package/src/api/impl/beacon/blocks/index.ts +7 -4
  194. package/src/api/impl/beacon/index.ts +15 -0
  195. package/src/api/impl/beacon/state/index.ts +43 -6
  196. package/src/api/impl/debug/index.ts +28 -19
  197. package/src/api/impl/validator/index.ts +24 -2
  198. package/src/chain/archiveStore/archiveStore.ts +19 -25
  199. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +5 -7
  200. package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +1 -1
  201. package/src/chain/archiveStore/historicalState/types.ts +2 -2
  202. package/src/chain/archiveStore/historicalState/worker.ts +1 -2
  203. package/src/chain/archiveStore/interface.ts +1 -1
  204. package/src/chain/archiveStore/utils/pruneHistory.ts +4 -1
  205. package/src/chain/blocks/importBlock.ts +16 -5
  206. package/src/chain/blocks/payloadEnvelopeInput/types.ts +2 -1
  207. package/src/chain/blocks/verifyBlock.ts +8 -6
  208. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +6 -3
  209. package/src/chain/chain.ts +115 -35
  210. package/src/chain/emitter.ts +7 -1
  211. package/src/chain/errors/envelopeReconstructionError.ts +3 -0
  212. package/src/chain/errors/gossipValidation.ts +2 -0
  213. package/src/chain/forkChoice/index.ts +2 -0
  214. package/src/chain/interface.ts +3 -2
  215. package/src/chain/opPools/aggregatedAttestationPool.ts +34 -10
  216. package/src/chain/opPools/proposerPreferencesPool.ts +14 -10
  217. package/src/chain/options.ts +3 -3
  218. package/src/chain/prepareNextSlot.ts +6 -3
  219. package/src/chain/produceBlock/computeNewStateRoot.ts +1 -1
  220. package/src/chain/produceBlock/produceBlockBody.ts +8 -1
  221. package/src/chain/regen/regen.ts +12 -4
  222. package/src/chain/seenCache/seenGossipBlockInput.ts +23 -0
  223. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +31 -13
  224. package/src/chain/shufflingCache.ts +84 -22
  225. package/src/chain/validatorMonitor.ts +75 -57
  226. package/src/db/beacon.ts +3 -0
  227. package/src/db/buckets.ts +1 -0
  228. package/src/db/interface.ts +2 -0
  229. package/src/db/repositories/earliestAvailableSlot.ts +19 -0
  230. package/src/execution/engine/disabled.ts +0 -8
  231. package/src/execution/engine/http.ts +1 -30
  232. package/src/execution/engine/interface.ts +2 -6
  233. package/src/execution/engine/mock.ts +1 -19
  234. package/src/execution/engine/types.ts +0 -10
  235. package/src/metrics/metrics/lodestar.ts +18 -0
  236. package/src/metrics/metrics.ts +21 -6
  237. package/src/network/processor/gossipHandlers.ts +93 -76
  238. package/src/network/processor/gossipValidatorFn.ts +13 -3
  239. package/src/network/processor/index.ts +89 -10
  240. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +1 -1
  241. package/src/node/nodejs.ts +35 -3
  242. package/src/sync/range/batch.ts +25 -19
  243. package/src/sync/range/chain.ts +15 -8
  244. package/src/sync/range/range.ts +76 -30
  245. package/src/sync/unknownBlock.ts +62 -25
  246. package/src/sync/utils/downloadByRange.ts +123 -58
  247. package/src/util/execution.ts +16 -8
@@ -123,6 +123,11 @@ export type ValidatorMonitorOpts = {
123
123
  validatorMonitorLogs?: boolean;
124
124
  };
125
125
 
126
+ export type NativeValidatorMonitor = {
127
+ registerLocalValidator(index: ValidatorIndex): void;
128
+ unregisterLocalValidator(index: ValidatorIndex): void;
129
+ };
130
+
126
131
  export const defaultValidatorMonitorOpts: ValidatorMonitorOpts = {
127
132
  validatorMonitorLogs: false,
128
133
  };
@@ -296,7 +301,8 @@ export function createValidatorMonitor(
296
301
  config: ChainForkConfig,
297
302
  genesisTime: number,
298
303
  logger: Logger,
299
- opts: ValidatorMonitorOpts
304
+ opts: ValidatorMonitorOpts,
305
+ nativeValidatorMonitor: NativeValidatorMonitor | null = null
300
306
  ): ValidatorMonitor {
301
307
  const logLevel = opts.validatorMonitorLogs ? LogLevel.info : LogLevel.debug;
302
308
  const log: LogHandler = (message: string, context?: LogData) => {
@@ -327,18 +333,23 @@ export function createValidatorMonitor(
327
333
  }));
328
334
 
329
335
  let lastRegisteredStatusEpoch = -1;
336
+ let lastAttestationSummaryEpoch = -1;
330
337
 
331
338
  // Track validator additions/removals per epoch for logging
332
339
  const addedValidatorsInEpoch: Set<ValidatorIndex> = new Set();
333
340
  const removedValidatorsInEpoch: Set<ValidatorIndex> = new Set();
334
341
 
335
- const validatorMonitorMetrics = metricsRegister ? createValidatorMonitorMetrics(metricsRegister) : null;
342
+ const shouldRegisterStateDerivedMetrics = nativeValidatorMonitor === null;
343
+ const validatorMonitorMetrics = metricsRegister
344
+ ? createValidatorMonitorMetrics(metricsRegister, shouldRegisterStateDerivedMetrics)
345
+ : null;
336
346
 
337
347
  const validatorMonitor: ValidatorMonitor = {
338
348
  registerLocalValidator(index) {
339
349
  const isNewValidator = !validators.has(index);
340
350
  validators.getOrDefault(index).lastRegisteredTimeMs = Date.now();
341
351
  if (isNewValidator) {
352
+ nativeValidatorMonitor?.registerLocalValidator(index);
342
353
  addedValidatorsInEpoch.add(index);
343
354
  }
344
355
  },
@@ -366,7 +377,7 @@ export function createValidatorMonitor(
366
377
  // Track total balance instead of per-validator balance to reduce metric cardinality
367
378
  let totalBalance = 0;
368
379
 
369
- for (const [index, monitoredValidator] of validators.entries()) {
380
+ for (const index of validators.keys()) {
370
381
  // We subtract two from the state of the epoch that generated these summaries.
371
382
  //
372
383
  // - One to account for it being the previous epoch.
@@ -380,68 +391,29 @@ export function createValidatorMonitor(
380
391
  );
381
392
 
382
393
  if (summary.isPrevSourceAttester) {
383
- validatorMonitorMetrics?.prevEpochOnChainSourceAttesterHit.inc();
394
+ validatorMonitorMetrics?.prevEpochOnChainSourceAttesterHit?.inc();
384
395
  } else {
385
- validatorMonitorMetrics?.prevEpochOnChainSourceAttesterMiss.inc();
396
+ validatorMonitorMetrics?.prevEpochOnChainSourceAttesterMiss?.inc();
386
397
  }
387
398
  if (summary.isPrevHeadAttester) {
388
- validatorMonitorMetrics?.prevEpochOnChainHeadAttesterHit.inc();
399
+ validatorMonitorMetrics?.prevEpochOnChainHeadAttesterHit?.inc();
389
400
  } else {
390
- validatorMonitorMetrics?.prevEpochOnChainHeadAttesterMiss.inc();
401
+ validatorMonitorMetrics?.prevEpochOnChainHeadAttesterMiss?.inc();
391
402
  }
392
403
  if (summary.isPrevTargetAttester) {
393
- validatorMonitorMetrics?.prevEpochOnChainTargetAttesterHit.inc();
404
+ validatorMonitorMetrics?.prevEpochOnChainTargetAttesterHit?.inc();
394
405
  } else {
395
- validatorMonitorMetrics?.prevEpochOnChainTargetAttesterMiss.inc();
396
- }
397
-
398
- const prevEpochSummary = monitoredValidator.summaries.get(previousEpoch);
399
- const attestationCorrectHead = prevEpochSummary?.attestationCorrectHead;
400
- if (attestationCorrectHead !== null && attestationCorrectHead !== undefined) {
401
- if (attestationCorrectHead) {
402
- validatorMonitorMetrics?.prevOnChainAttesterCorrectHead.inc();
403
- } else {
404
- validatorMonitorMetrics?.prevOnChainAttesterIncorrectHead.inc();
405
- }
406
- }
407
-
408
- const attestationMinBlockInclusionDistance = prevEpochSummary?.attestationMinBlockInclusionDistance;
409
- const inclusionDistance =
410
- attestationMinBlockInclusionDistance != null && attestationMinBlockInclusionDistance > 0
411
- ? // altair, attestation is not missed
412
- attestationMinBlockInclusionDistance
413
- : summary.inclusionDistance
414
- ? // phase0, this is from the state transition
415
- summary.inclusionDistance
416
- : null;
417
-
418
- if (inclusionDistance !== null) {
419
- validatorMonitorMetrics?.prevEpochOnChainInclusionDistance.observe(inclusionDistance);
420
- validatorMonitorMetrics?.prevEpochOnChainAttesterHit.inc();
421
- } else {
422
- validatorMonitorMetrics?.prevEpochOnChainAttesterMiss.inc();
406
+ validatorMonitorMetrics?.prevEpochOnChainTargetAttesterMiss?.inc();
423
407
  }
424
408
 
425
409
  const balance = balances?.[index];
426
410
  if (balance !== undefined) {
427
411
  totalBalance += balance;
428
412
  }
429
-
430
- if (!summary.isPrevSourceAttester || !summary.isPrevTargetAttester || !summary.isPrevHeadAttester) {
431
- log("Failed attestation in previous epoch", {
432
- validator: index,
433
- prevEpoch: currentEpoch - 1,
434
- isPrevSourceAttester: summary.isPrevSourceAttester,
435
- isPrevHeadAttester: summary.isPrevHeadAttester,
436
- isPrevTargetAttester: summary.isPrevTargetAttester,
437
- // inclusionDistance is not available in summary since altair
438
- inclusionDistance,
439
- });
440
- }
441
413
  }
442
414
 
443
415
  if (balances !== undefined) {
444
- validatorMonitorMetrics?.prevEpochOnChainBalance.set(totalBalance);
416
+ validatorMonitorMetrics?.prevEpochOnChainBalance?.set(totalBalance);
445
417
  }
446
418
  },
447
419
 
@@ -732,6 +704,7 @@ export function createValidatorMonitor(
732
704
  // Prune validators not seen in a while
733
705
  for (const [index, validator] of validators.entries()) {
734
706
  if (Date.now() - validator.lastRegisteredTimeMs > retainRegisteredValidatorsMs) {
707
+ nativeValidatorMonitor?.unregisterLocalValidator(index);
735
708
  validators.delete(index);
736
709
  removedValidatorsInEpoch.add(index);
737
710
  }
@@ -767,6 +740,38 @@ export function createValidatorMonitor(
767
740
  return;
768
741
  }
769
742
 
743
+ // On-chain attestation summary of prevEpoch. Reads only the epoch summaries filled by
744
+ // registerAttestationInBlock(), so it works with both TS and native state transition.
745
+ if (prevEpoch > lastAttestationSummaryEpoch) {
746
+ lastAttestationSummaryEpoch = prevEpoch;
747
+
748
+ for (const monitoredValidator of validators.values()) {
749
+ const prevEpochSummary = monitoredValidator.summaries.get(prevEpoch);
750
+ const attestationCorrectHead = prevEpochSummary?.attestationCorrectHead;
751
+ if (attestationCorrectHead !== null && attestationCorrectHead !== undefined) {
752
+ if (attestationCorrectHead) {
753
+ validatorMonitorMetrics?.prevOnChainAttesterCorrectHead.inc();
754
+ } else {
755
+ validatorMonitorMetrics?.prevOnChainAttesterIncorrectHead.inc();
756
+ }
757
+ }
758
+
759
+ const attestationMinBlockInclusionDistance = prevEpochSummary?.attestationMinBlockInclusionDistance;
760
+ const inclusionDistance =
761
+ attestationMinBlockInclusionDistance != null && attestationMinBlockInclusionDistance > 0
762
+ ? // altair, attestation is not missed
763
+ attestationMinBlockInclusionDistance
764
+ : null;
765
+
766
+ if (inclusionDistance !== null) {
767
+ validatorMonitorMetrics?.prevEpochOnChainInclusionDistance.observe(inclusionDistance);
768
+ validatorMonitorMetrics?.prevEpochOnChainAttesterHit.inc();
769
+ } else {
770
+ validatorMonitorMetrics?.prevEpochOnChainAttesterMiss.inc();
771
+ }
772
+ }
773
+ }
774
+
770
775
  const rootCache = new RootHexCache(headState);
771
776
 
772
777
  if (isStatePostAltair(headState)) {
@@ -784,6 +789,17 @@ export function createValidatorMonitor(
784
789
  epoch: prevEpoch,
785
790
  summary,
786
791
  });
792
+
793
+ if (!flags.timelySource || !flags.timelyTarget || !flags.timelyHead) {
794
+ log("Failed attestation in previous epoch", {
795
+ validator: index,
796
+ prevEpoch,
797
+ isPrevSourceAttester: flags.timelySource,
798
+ isPrevHeadAttester: flags.timelyHead,
799
+ isPrevTargetAttester: flags.timelyTarget,
800
+ inclusionDistance: validator.summaries.get(prevEpoch)?.attestationMinBlockInclusionDistance ?? null,
801
+ });
802
+ }
787
803
  }
788
804
  }
789
805
 
@@ -1198,7 +1214,9 @@ export class RootHexCache {
1198
1214
  }
1199
1215
  }
1200
1216
 
1201
- function createValidatorMonitorMetrics(register: RegistryMetricCreator) {
1217
+ function createValidatorMonitorMetrics(register: RegistryMetricCreator, registerStateDerivedMetrics = true) {
1218
+ const stateDerivedRegister = registerStateDerivedMetrics ? register : null;
1219
+
1202
1220
  return {
1203
1221
  validatorsConnected: register.gauge({
1204
1222
  name: "validator_monitor_validators",
@@ -1217,7 +1235,7 @@ function createValidatorMonitorMetrics(register: RegistryMetricCreator) {
1217
1235
  }),
1218
1236
 
1219
1237
  // Validator Monitor Metrics (per-epoch summaries)
1220
- prevEpochOnChainBalance: register.gauge({
1238
+ prevEpochOnChainBalance: stateDerivedRegister?.gauge({
1221
1239
  name: "validator_monitor_prev_epoch_on_chain_balance",
1222
1240
  help: "Total balance of all monitored validators after an epoch",
1223
1241
  }),
@@ -1229,19 +1247,19 @@ function createValidatorMonitorMetrics(register: RegistryMetricCreator) {
1229
1247
  name: "validator_monitor_prev_epoch_on_chain_attester_miss_total",
1230
1248
  help: "Incremented if validator's submitted attestation is not included in any blocks",
1231
1249
  }),
1232
- prevEpochOnChainSourceAttesterHit: register.gauge({
1250
+ prevEpochOnChainSourceAttesterHit: stateDerivedRegister?.gauge({
1233
1251
  name: "validator_monitor_prev_epoch_on_chain_source_attester_hit_total",
1234
1252
  help: "Incremented if the validator is flagged as a previous epoch source attester during per epoch processing",
1235
1253
  }),
1236
- prevEpochOnChainSourceAttesterMiss: register.gauge({
1254
+ prevEpochOnChainSourceAttesterMiss: stateDerivedRegister?.gauge({
1237
1255
  name: "validator_monitor_prev_epoch_on_chain_source_attester_miss_total",
1238
1256
  help: "Incremented if the validator is not flagged as a previous epoch source attester during per epoch processing",
1239
1257
  }),
1240
- prevEpochOnChainHeadAttesterHit: register.gauge({
1258
+ prevEpochOnChainHeadAttesterHit: stateDerivedRegister?.gauge({
1241
1259
  name: "validator_monitor_prev_epoch_on_chain_head_attester_hit_total",
1242
1260
  help: "Incremented if the validator is flagged as a previous epoch head attester during per epoch processing",
1243
1261
  }),
1244
- prevEpochOnChainHeadAttesterMiss: register.gauge({
1262
+ prevEpochOnChainHeadAttesterMiss: stateDerivedRegister?.gauge({
1245
1263
  name: "validator_monitor_prev_epoch_on_chain_head_attester_miss_total",
1246
1264
  help: "Incremented if the validator is not flagged as a previous epoch head attester during per epoch processing",
1247
1265
  }),
@@ -1253,11 +1271,11 @@ function createValidatorMonitorMetrics(register: RegistryMetricCreator) {
1253
1271
  name: "validator_monitor_prev_epoch_on_chain_attester_incorrect_head_total",
1254
1272
  help: "Total count of times a validator votes incorrect head",
1255
1273
  }),
1256
- prevEpochOnChainTargetAttesterHit: register.gauge({
1274
+ prevEpochOnChainTargetAttesterHit: stateDerivedRegister?.gauge({
1257
1275
  name: "validator_monitor_prev_epoch_on_chain_target_attester_hit_total",
1258
1276
  help: "Incremented if the validator is flagged as a previous epoch target attester during per epoch processing",
1259
1277
  }),
1260
- prevEpochOnChainTargetAttesterMiss: register.gauge({
1278
+ prevEpochOnChainTargetAttesterMiss: stateDerivedRegister?.gauge({
1261
1279
  name: "validator_monitor_prev_epoch_on_chain_target_attester_miss_total",
1262
1280
  help: "Incremented if the validator is not flagged as a previous epoch target attester during per epoch processing",
1263
1281
  }),
package/src/db/beacon.ts CHANGED
@@ -8,6 +8,7 @@ import {FlatFileStore} from "./flatFileStore/flatFileStore.js";
8
8
  import type {FlatFileStoreMetrics} from "./flatFileStore/metrics.js";
9
9
  import {IBeaconDb} from "./interface.js";
10
10
  import {CheckpointStateRepository} from "./repositories/checkpointState.js";
11
+ import {EarliestAvailableSlotRepository} from "./repositories/earliestAvailableSlot.js";
11
12
  import {
12
13
  AttesterSlashingRepository,
13
14
  BLSToExecutionChangeRepository,
@@ -48,6 +49,7 @@ export class BeaconDb implements IBeaconDb {
48
49
 
49
50
  stateArchive: StateArchiveRepository;
50
51
  checkpointState: CheckpointStateRepository;
52
+ earliestAvailableSlot: EarliestAvailableSlotRepository;
51
53
 
52
54
  voluntaryExit: VoluntaryExitRepository;
53
55
  proposerSlashing: ProposerSlashingRepository;
@@ -83,6 +85,7 @@ export class BeaconDb implements IBeaconDb {
83
85
 
84
86
  this.stateArchive = new StateArchiveRepository(config, db);
85
87
  this.checkpointState = new CheckpointStateRepository(config, db);
88
+ this.earliestAvailableSlot = new EarliestAvailableSlotRepository(db);
86
89
  this.voluntaryExit = new VoluntaryExitRepository(config, db);
87
90
  this.blsToExecutionChange = new BLSToExecutionChangeRepository(config, db);
88
91
  this.proposerSlashing = new ProposerSlashingRepository(config, db);
package/src/db/buckets.ts CHANGED
@@ -72,6 +72,7 @@ export enum Bucket {
72
72
 
73
73
  gloas_executionPayloadEnvelope = 59, // GLOAS BeaconBlockRoot -> SignedExecutionPayloadEnvelope
74
74
  gloas_executionPayloadEnvelopeArchive = 60, // GLOAS Slot -> SignedExecutionPayloadEnvelope, or 0x00 + SignedExecutionPayloadHeaderEnvelope
75
+ earliestAvailableSlot = 61, // singleton -> Slot
75
76
  }
76
77
 
77
78
  export function getBucketNameByValue<T extends Bucket>(enumValue: T): keyof typeof Bucket {
@@ -3,6 +3,7 @@ import {Slot} from "@lodestar/types";
3
3
  import type {IDataColumnStore} from "./dataColumnStore.js";
4
4
  import type {FlatFileStoreMetrics} from "./flatFileStore/metrics.js";
5
5
  import {CheckpointStateRepository} from "./repositories/checkpointState.js";
6
+ import {EarliestAvailableSlotRepository} from "./repositories/earliestAvailableSlot.js";
6
7
  import {
7
8
  AttesterSlashingRepository,
8
9
  BLSToExecutionChangeRepository,
@@ -46,6 +47,7 @@ export interface IBeaconDb {
46
47
  stateArchive: StateArchiveRepository;
47
48
  // checkpoint states
48
49
  checkpointState: CheckpointStateRepository;
50
+ earliestAvailableSlot: EarliestAvailableSlotRepository;
49
51
 
50
52
  // op pool
51
53
  voluntaryExit: VoluntaryExitRepository;
@@ -0,0 +1,19 @@
1
+ import {Db, encodeKey} from "@lodestar/db";
2
+ import {Slot, ssz} from "@lodestar/types";
3
+ import {Bucket, getBucketNameByValue} from "../buckets.js";
4
+
5
+ export class EarliestAvailableSlotRepository {
6
+ private readonly key = encodeKey(Bucket.earliestAvailableSlot, 0);
7
+ private readonly opts = {bucketId: getBucketNameByValue(Bucket.earliestAvailableSlot)};
8
+
9
+ constructor(private readonly db: Db) {}
10
+
11
+ async get(): Promise<Slot | null> {
12
+ const bytes = await this.db.get(this.key, this.opts);
13
+ return bytes === null ? null : ssz.Slot.deserialize(bytes);
14
+ }
15
+
16
+ async set(slot: Slot): Promise<void> {
17
+ await this.db.put(this.key, ssz.Slot.serialize(slot), this.opts);
18
+ }
19
+ }
@@ -21,18 +21,10 @@ export class ExecutionEngineDisabled implements IExecutionEngine {
21
21
  throw Error("Execution engine disabled");
22
22
  }
23
23
 
24
- getPayloadBodiesByHash(): Promise<never> {
25
- throw Error("Execution engine disabled");
26
- }
27
-
28
24
  getPayloadBodiesByHashV2(): Promise<never> {
29
25
  throw Error("Execution engine disabled");
30
26
  }
31
27
 
32
- getPayloadBodiesByRange(): Promise<never> {
33
- throw Error("Execution engine disabled");
34
- }
35
-
36
28
  getBlobs(): Promise<never> {
37
29
  throw Error("Execution engine disabled");
38
30
  }
@@ -31,13 +31,11 @@ import {
31
31
  BLOB_AND_PROOF_V2_RPC_BYTES,
32
32
  EngineApiRpcParamTypes,
33
33
  EngineApiRpcReturnTypes,
34
- ExecutionPayloadBody,
35
34
  ExecutionPayloadBodyV2,
36
35
  assertReqSizeLimit,
37
36
  deserializeBlobAndProofs,
38
37
  deserializeBlobAndProofsV2,
39
38
  deserializeBlobAndProofsV2IntoBytes,
40
- deserializeExecutionPayloadBody,
41
39
  deserializeExecutionPayloadBodyV2,
42
40
  parseExecutionPayload,
43
41
  serializeBeaconBlockRoot,
@@ -46,7 +44,7 @@ import {
46
44
  serializePayloadAttributes,
47
45
  serializeVersionedHashes,
48
46
  } from "./types.js";
49
- import {bytesToData, getExecutionEngineState, numToQuantity} from "./utils.js";
47
+ import {bytesToData, getExecutionEngineState} from "./utils.js";
50
48
 
51
49
  export type ExecutionEngineModules = {
52
50
  signal: AbortSignal;
@@ -114,7 +112,6 @@ const notifyNewPayloadOpts: ReqOpts = {routeId: "notifyNewPayload"};
114
112
  const forkchoiceUpdatedV1Opts: ReqOpts = {routeId: "forkchoiceUpdated"};
115
113
  const getPayloadOpts: ReqOpts = {routeId: "getPayload"};
116
114
  const getPayloadBodiesByHashOpts: ReqOpts = {routeId: "getPayloadBodiesByHash"};
117
- const getPayloadBodiesByRangeOpts: ReqOpts = {routeId: "getPayloadBodiesByRange"};
118
115
  const getBlobsV1Opts: ReqOpts = {routeId: "getBlobsV1"};
119
116
  const getBlobsV2Opts: ReqOpts = {routeId: "getBlobsV2"};
120
117
  const getClientVersionOpts: ReqOpts = {routeId: "getClientVersion"};
@@ -468,16 +465,6 @@ export class ExecutionEngineHttp implements IExecutionEngine {
468
465
  this.payloadIdCache.prune();
469
466
  }
470
467
 
471
- async getPayloadBodiesByHash(_fork: ForkName, blockHashes: RootHex[]): Promise<(ExecutionPayloadBody | null)[]> {
472
- const method = "engine_getPayloadBodiesByHashV1";
473
- assertReqSizeLimit(blockHashes.length, 32);
474
- const response = await this.rpc.fetchWithRetries<
475
- EngineApiRpcReturnTypes[typeof method],
476
- EngineApiRpcParamTypes[typeof method]
477
- >({method, params: [blockHashes]}, getPayloadBodiesByHashOpts);
478
- return response.map(deserializeExecutionPayloadBody);
479
- }
480
-
481
468
  async getPayloadBodiesByHashV2(blockHashes: RootHex[]): Promise<(ExecutionPayloadBodyV2 | null)[]> {
482
469
  const method = "engine_getPayloadBodiesByHashV2";
483
470
  assertReqSizeLimit(blockHashes.length, 32);
@@ -488,22 +475,6 @@ export class ExecutionEngineHttp implements IExecutionEngine {
488
475
  return response.map(deserializeExecutionPayloadBodyV2);
489
476
  }
490
477
 
491
- async getPayloadBodiesByRange(
492
- _fork: ForkName,
493
- startBlockNumber: number,
494
- blockCount: number
495
- ): Promise<(ExecutionPayloadBody | null)[]> {
496
- const method = "engine_getPayloadBodiesByRangeV1";
497
- assertReqSizeLimit(blockCount, 32);
498
- const start = numToQuantity(startBlockNumber);
499
- const count = numToQuantity(blockCount);
500
- const response = await this.rpc.fetchWithRetries<
501
- EngineApiRpcReturnTypes[typeof method],
502
- EngineApiRpcParamTypes[typeof method]
503
- >({method, params: [start, count]}, getPayloadBodiesByRangeOpts);
504
- return response.map(deserializeExecutionPayloadBody);
505
- }
506
-
507
478
  async getBlobs(
508
479
  fork: ForkPostFulu,
509
480
  versionedHashes: VersionedHashes,
@@ -13,7 +13,7 @@ import {BlobsBundle, ExecutionPayload, ExecutionRequests, Root, RootHex, Wei, ca
13
13
  import {BlobAndProof} from "@lodestar/types/deneb";
14
14
  import {BlobAndProofV2} from "@lodestar/types/fulu";
15
15
  import {PayloadId, PayloadIdCache, WithdrawalV1} from "./payloadIdCache.js";
16
- import {ExecutionPayloadBody, ExecutionPayloadBodyV2} from "./types.js";
16
+ import {ExecutionPayloadBodyV2} from "./types.js";
17
17
  import {DATA} from "./utils.js";
18
18
 
19
19
  export {PayloadIdCache, type PayloadId, type WithdrawalV1};
@@ -170,13 +170,9 @@ export interface IExecutionEngine {
170
170
  shouldOverrideBuilder?: boolean;
171
171
  }>;
172
172
 
173
- getPayloadBodiesByHash(fork: ForkName, blockHash: DATA[]): Promise<(ExecutionPayloadBody | null)[]>;
174
-
175
- /** Amsterdam: like V1 but also returns the block access list (null if the EL no longer has it) */
173
+ /** Amsterdam: payload bodies including the block access list (null if the EL no longer has it) */
176
174
  getPayloadBodiesByHashV2(blockHash: DATA[]): Promise<(ExecutionPayloadBodyV2 | null)[]>;
177
175
 
178
- getPayloadBodiesByRange(fork: ForkName, start: number, count: number): Promise<(ExecutionPayloadBody | null)[]>;
179
-
180
176
  getBlobs(
181
177
  fork: ForkPostFulu,
182
178
  versionedHashes: VersionedHashes,
@@ -22,7 +22,6 @@ import {
22
22
  BlobsBundleRpc,
23
23
  EngineApiRpcParamTypes,
24
24
  EngineApiRpcReturnTypes,
25
- ExecutionPayloadBodyRpc,
26
25
  ExecutionPayloadBodyV2Rpc,
27
26
  ExecutionPayloadRpc,
28
27
  ExecutionRequestsRpc,
@@ -50,7 +49,7 @@ type ExecutionBlock = {
50
49
  blockHash: RootHex;
51
50
  timestamp: number;
52
51
  blockNumber: number;
53
- /** Bodies as received via newPayload, served back by engine_getPayloadBodiesByHash{V1,V2} */
52
+ /** Bodies as received via newPayload, served back by engine_getPayloadBodiesByHashV2 */
54
53
  body: ExecutionPayloadBodyV2Rpc;
55
54
  };
56
55
 
@@ -148,23 +147,13 @@ export class ExecutionEngineMockBackend implements JsonRpcBackend {
148
147
  engine_getPayloadV4: this.getPayloadV5.bind(this),
149
148
  engine_getPayloadV5: this.getPayloadV5.bind(this),
150
149
  engine_getPayloadV6: this.getPayloadV5.bind(this),
151
- engine_getPayloadBodiesByHashV1: this.getPayloadBodiesByHash.bind(this),
152
150
  engine_getPayloadBodiesByHashV2: this.getPayloadBodiesByHashV2.bind(this),
153
- engine_getPayloadBodiesByRangeV1: this.getPayloadBodiesByRange.bind(this),
154
151
  engine_getClientVersionV1: this.getClientVersionV1.bind(this),
155
152
  engine_getBlobsV1: this.getBlobs.bind(this),
156
153
  engine_getBlobsV2: this.getBlobsV2.bind(this),
157
154
  };
158
155
  }
159
156
 
160
- private getPayloadBodiesByHash(
161
- blockHashes: EngineApiRpcParamTypes["engine_getPayloadBodiesByHashV1"][0]
162
- ): EngineApiRpcReturnTypes["engine_getPayloadBodiesByHashV1"] {
163
- return this.getPayloadBodiesByHashV2(blockHashes).map((body) =>
164
- body ? {transactions: body.transactions, withdrawals: body.withdrawals} : null
165
- );
166
- }
167
-
168
157
  private getPayloadBodiesByHashV2(
169
158
  blockHashes: EngineApiRpcParamTypes["engine_getPayloadBodiesByHashV2"][0]
170
159
  ): EngineApiRpcReturnTypes["engine_getPayloadBodiesByHashV2"] {
@@ -172,13 +161,6 @@ export class ExecutionEngineMockBackend implements JsonRpcBackend {
172
161
  return blockHashes.map((hash) => this.validBlocks.get(hash)?.body ?? null);
173
162
  }
174
163
 
175
- private getPayloadBodiesByRange(
176
- _start: EngineApiRpcParamTypes["engine_getPayloadBodiesByRangeV1"][0],
177
- _count: EngineApiRpcParamTypes["engine_getPayloadBodiesByRangeV1"][1]
178
- ): EngineApiRpcReturnTypes["engine_getPayloadBodiesByRangeV1"] {
179
- return [] as ExecutionPayloadBodyRpc[];
180
- }
181
-
182
164
  /**
183
165
  * Mock manipulator to add predefined responses before execution engine client calls
184
166
  */
@@ -88,15 +88,8 @@ export type EngineApiRpcParamTypes = {
88
88
  /**
89
89
  * 1. Array of DATA - Array of block_hash field values of the ExecutionPayload structure
90
90
  * */
91
- engine_getPayloadBodiesByHashV1: DATA[][];
92
91
  engine_getPayloadBodiesByHashV2: DATA[][];
93
92
 
94
- /**
95
- * 1. start: QUANTITY, 64 bits - Starting block number
96
- * 2. count: QUANTITY, 64 bits - Number of blocks to return
97
- */
98
- engine_getPayloadBodiesByRangeV1: [start: QUANTITY, count: QUANTITY];
99
-
100
93
  /**
101
94
  * Object - Instance of ClientVersion
102
95
  */
@@ -148,11 +141,8 @@ export type EngineApiRpcReturnTypes = {
148
141
  engine_getPayloadV5: ExecutionPayloadResponse;
149
142
  engine_getPayloadV6: ExecutionPayloadResponse;
150
143
 
151
- engine_getPayloadBodiesByHashV1: (ExecutionPayloadBodyRpc | null)[];
152
144
  engine_getPayloadBodiesByHashV2: (ExecutionPayloadBodyV2Rpc | null)[];
153
145
 
154
- engine_getPayloadBodiesByRangeV1: (ExecutionPayloadBodyRpc | null)[];
155
-
156
146
  engine_getClientVersionV1: ClientVersionRpc[];
157
147
 
158
148
  engine_getBlobsV1: (BlobAndProofRpc | null)[];
@@ -20,6 +20,7 @@ import {InsertOutcome} from "../../chain/opPools/types.js";
20
20
  import {RegenCaller, RegenFnName} from "../../chain/regen/interface.js";
21
21
  import {ReprocessStatus} from "../../chain/reprocess.js";
22
22
  import {RejectReason} from "../../chain/seenCache/seenAttestationData.js";
23
+ import type {ShufflingPromiseCancelReason} from "../../chain/shufflingCache.js";
23
24
  import {CacheItemType} from "../../chain/stateCache/types.js";
24
25
  import {OpSource} from "../../chain/validatorMonitor.js";
25
26
  import type {FlatFileStoreOperation} from "../../db/flatFileStore/metrics.js";
@@ -1281,6 +1282,10 @@ export function createLodestarMetrics(
1281
1282
  name: "lodestar_oppool_aggregated_attestation_pool_packed_attestations_seen_committees_total",
1282
1283
  help: "Total number of committees for which all members are seen when producing packed attestations",
1283
1284
  }),
1285
+ missingShufflingCommittees: register.gauge({
1286
+ name: "lodestar_oppool_aggregated_attestation_pool_packed_attestations_missing_shuffling_committees_total",
1287
+ help: "Total number of committees skipped due to missing shuffling when producing packed attestations",
1288
+ }),
1284
1289
  },
1285
1290
  },
1286
1291
  attestationPool: {
@@ -1614,6 +1619,19 @@ export function createLodestarMetrics(
1614
1619
  name: "lodestar_shuffling_cache_size",
1615
1620
  help: "Shuffling cache size",
1616
1621
  }),
1622
+ epochs: register.gauge({
1623
+ name: "lodestar_shuffling_cache_epochs",
1624
+ help: "Number of epochs in shuffling cache",
1625
+ }),
1626
+ prunedShufflings: register.counter({
1627
+ name: "lodestar_shuffling_cache_pruned_shufflings_total",
1628
+ help: "Total number of shufflings pruned from shuffling cache",
1629
+ }),
1630
+ cancelledPromises: register.counter<{reason: ShufflingPromiseCancelReason}>({
1631
+ name: "lodestar_shuffling_cache_cancelled_promises_total",
1632
+ help: "Total number of shuffling promises resolved with null",
1633
+ labelNames: ["reason"],
1634
+ }),
1617
1635
  insertPromiseCount: register.gauge({
1618
1636
  name: "lodestar_shuffling_cache_insert_promise_count",
1619
1637
  help: "Total number of times insertPromise is called",
@@ -9,27 +9,42 @@ import {RegistryMetricCreator} from "./utils/registryMetricCreator.js";
9
9
 
10
10
  export type Metrics = BeaconMetrics &
11
11
  ForkChoiceMetrics &
12
- BeaconStateTransitionMetrics &
13
- LodestarMetrics & {register: RegistryMetricCreator; close: () => void};
12
+ LodestarMetrics & {
13
+ /** Null when we use native state transition metrics instead */
14
+ stateTransition: BeaconStateTransitionMetrics | null;
15
+ register: RegistryMetricCreator;
16
+ close: () => void;
17
+ };
18
+
19
+ export type CreateMetricsOptions = {
20
+ /*
21
+ * Toggle inclusion of state transition metrics.
22
+ *
23
+ * False when native state transition is used, so we
24
+ * can grab metrics from the native implementation instead.
25
+ * */
26
+ includeStateTransitionMetrics?: boolean;
27
+ collectNodeMetrics?: boolean;
28
+ };
14
29
 
15
30
  export function createMetrics(
16
31
  opts: MetricsOptions,
17
32
  genesisTime: number,
18
33
  externalRegistries: Registry[] = [],
19
- {collectNodeMetrics = true}: {collectNodeMetrics?: boolean} = {}
34
+ createOpts: CreateMetricsOptions = {}
20
35
  ): Metrics {
21
36
  const register = new RegistryMetricCreator();
22
37
  const beacon = createBeaconMetrics(register);
23
38
  const forkChoice = getForkChoiceMetrics(register);
24
39
  const lodestar = createLodestarMetrics(register, opts.metadata, genesisTime);
25
- const stateTransition = getMetrics(register);
40
+ const stateTransition = createOpts.includeStateTransitionMetrics === false ? null : getMetrics(register);
26
41
 
27
42
  const onUnhandledRejection = (_error: unknown): void => {
28
43
  lodestar.unhandledPromiseRejections.inc();
29
44
  };
30
45
  process.on("unhandledRejection", onUnhandledRejection);
31
46
 
32
- const nodeJsMetricsClose = collectNodeMetrics ? collectNodeJSMetrics(register) : (): void => {};
47
+ const nodeJsMetricsClose = createOpts.collectNodeMetrics === false ? (): void => {} : collectNodeJSMetrics(register);
33
48
  const close = (): void => {
34
49
  process.removeListener("unhandledRejection", onUnhandledRejection);
35
50
  nodeJsMetricsClose();
@@ -46,7 +61,7 @@ export function createMetrics(
46
61
  ...beacon,
47
62
  ...forkChoice,
48
63
  ...lodestar,
49
- ...stateTransition,
64
+ stateTransition,
50
65
  register,
51
66
  close,
52
67
  };