@lodestar/beacon-node 1.50.0-dev.f2d839a25c → 1.50.0-dev.fc618d94e9

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 (245) 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/pool/index.js +4 -4
  8. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  9. package/lib/api/impl/validator/index.d.ts +1 -0
  10. package/lib/api/impl/validator/index.d.ts.map +1 -1
  11. package/lib/api/impl/validator/index.js +17 -1
  12. package/lib/api/impl/validator/index.js.map +1 -1
  13. package/lib/chain/archiveStore/archiveStore.d.ts +1 -0
  14. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  15. package/lib/chain/archiveStore/archiveStore.js +7 -3
  16. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  17. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +2 -2
  18. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  19. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +5 -7
  20. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  21. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -1
  22. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
  23. package/lib/chain/archiveStore/historicalState/types.d.ts +2 -2
  24. package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
  25. package/lib/chain/archiveStore/historicalState/worker.js +1 -1
  26. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  27. package/lib/chain/archiveStore/interface.d.ts +1 -1
  28. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  29. package/lib/chain/archiveStore/utils/pruneHistory.d.ts +4 -1
  30. package/lib/chain/archiveStore/utils/pruneHistory.d.ts.map +1 -1
  31. package/lib/chain/archiveStore/utils/pruneHistory.js +4 -3
  32. package/lib/chain/archiveStore/utils/pruneHistory.js.map +1 -1
  33. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  34. package/lib/chain/blocks/importBlock.js +4 -0
  35. package/lib/chain/blocks/importBlock.js.map +1 -1
  36. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +2 -1
  37. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  38. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  39. package/lib/chain/blocks/verifyBlock.js +1 -1
  40. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  41. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts +2 -1
  42. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  43. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +5 -4
  44. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  45. package/lib/chain/chain.d.ts +6 -4
  46. package/lib/chain/chain.d.ts.map +1 -1
  47. package/lib/chain/chain.js +43 -16
  48. package/lib/chain/chain.js.map +1 -1
  49. package/lib/chain/emitter.d.ts +7 -1
  50. package/lib/chain/emitter.d.ts.map +1 -1
  51. package/lib/chain/emitter.js +5 -0
  52. package/lib/chain/emitter.js.map +1 -1
  53. package/lib/chain/errors/envelopeReconstructionError.d.ts +5 -0
  54. package/lib/chain/errors/envelopeReconstructionError.d.ts.map +1 -1
  55. package/lib/chain/errors/envelopeReconstructionError.js +2 -0
  56. package/lib/chain/errors/envelopeReconstructionError.js.map +1 -1
  57. package/lib/chain/errors/gossipValidation.d.ts +3 -1
  58. package/lib/chain/errors/gossipValidation.d.ts.map +1 -1
  59. package/lib/chain/errors/gossipValidation.js +2 -0
  60. package/lib/chain/errors/gossipValidation.js.map +1 -1
  61. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  62. package/lib/chain/forkChoice/index.js +2 -0
  63. package/lib/chain/forkChoice/index.js.map +1 -1
  64. package/lib/chain/initState.d.ts +2 -9
  65. package/lib/chain/initState.d.ts.map +1 -1
  66. package/lib/chain/initState.js +5 -38
  67. package/lib/chain/initState.js.map +1 -1
  68. package/lib/chain/interface.d.ts +2 -2
  69. package/lib/chain/interface.d.ts.map +1 -1
  70. package/lib/chain/opPools/opPool.d.ts +5 -4
  71. package/lib/chain/opPools/opPool.d.ts.map +1 -1
  72. package/lib/chain/opPools/opPool.js +62 -18
  73. package/lib/chain/opPools/opPool.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/opPools/utils.d.ts +4 -1
  79. package/lib/chain/opPools/utils.d.ts.map +1 -1
  80. package/lib/chain/opPools/utils.js +11 -1
  81. package/lib/chain/opPools/utils.js.map +1 -1
  82. package/lib/chain/options.d.ts +1 -1
  83. package/lib/chain/options.d.ts.map +1 -1
  84. package/lib/chain/options.js +1 -1
  85. package/lib/chain/options.js.map +1 -1
  86. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  87. package/lib/chain/prepareNextSlot.js +5 -2
  88. package/lib/chain/prepareNextSlot.js.map +1 -1
  89. package/lib/chain/produceBlock/computeNewStateRoot.js +1 -1
  90. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  91. package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -1
  92. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  93. package/lib/chain/produceBlock/produceBlockBody.js +6 -2
  94. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  95. package/lib/chain/regen/regen.d.ts +2 -0
  96. package/lib/chain/regen/regen.d.ts.map +1 -1
  97. package/lib/chain/regen/regen.js +10 -4
  98. package/lib/chain/regen/regen.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/validation/attesterSlashing.d.ts +4 -4
  104. package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
  105. package/lib/chain/validation/attesterSlashing.js +3 -0
  106. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  107. package/lib/chain/validation/proposerSlashing.d.ts +3 -3
  108. package/lib/chain/validation/proposerSlashing.d.ts.map +1 -1
  109. package/lib/chain/validation/proposerSlashing.js +3 -0
  110. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  111. package/lib/chain/validatorMonitor.d.ts +5 -1
  112. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  113. package/lib/chain/validatorMonitor.js +64 -54
  114. package/lib/chain/validatorMonitor.js.map +1 -1
  115. package/lib/db/beacon.d.ts.map +1 -1
  116. package/lib/db/beacon.js +2 -0
  117. package/lib/db/beacon.js.map +1 -1
  118. package/lib/db/repositories/proposerSlashing.d.ts +1 -0
  119. package/lib/db/repositories/proposerSlashing.d.ts.map +1 -1
  120. package/lib/db/repositories/proposerSlashing.js +5 -1
  121. package/lib/db/repositories/proposerSlashing.js.map +1 -1
  122. package/lib/execution/engine/disabled.d.ts +0 -2
  123. package/lib/execution/engine/disabled.d.ts.map +1 -1
  124. package/lib/execution/engine/disabled.js +0 -6
  125. package/lib/execution/engine/disabled.js.map +1 -1
  126. package/lib/execution/engine/http.d.ts +1 -3
  127. package/lib/execution/engine/http.d.ts.map +1 -1
  128. package/lib/execution/engine/http.js +2 -17
  129. package/lib/execution/engine/http.js.map +1 -1
  130. package/lib/execution/engine/interface.d.ts +2 -4
  131. package/lib/execution/engine/interface.d.ts.map +1 -1
  132. package/lib/execution/engine/mock.d.ts +0 -2
  133. package/lib/execution/engine/mock.d.ts.map +1 -1
  134. package/lib/execution/engine/mock.js +0 -8
  135. package/lib/execution/engine/mock.js.map +1 -1
  136. package/lib/execution/engine/types.d.ts +0 -8
  137. package/lib/execution/engine/types.d.ts.map +1 -1
  138. package/lib/execution/engine/types.js.map +1 -1
  139. package/lib/index.d.ts +1 -1
  140. package/lib/index.d.ts.map +1 -1
  141. package/lib/index.js +1 -1
  142. package/lib/index.js.map +1 -1
  143. package/lib/metrics/metrics.d.ts +7 -3
  144. package/lib/metrics/metrics.d.ts.map +1 -1
  145. package/lib/metrics/metrics.js +4 -4
  146. package/lib/metrics/metrics.js.map +1 -1
  147. package/lib/network/metadata.d.ts +1 -1
  148. package/lib/network/metadata.d.ts.map +1 -1
  149. package/lib/network/metadata.js +17 -17
  150. package/lib/network/metadata.js.map +1 -1
  151. package/lib/network/peers/datastore.d.ts +9 -9
  152. package/lib/network/peers/datastore.d.ts.map +1 -1
  153. package/lib/network/peers/datastore.js +36 -36
  154. package/lib/network/peers/datastore.js.map +1 -1
  155. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  156. package/lib/network/processor/gossipHandlers.js +7 -4
  157. package/lib/network/processor/gossipHandlers.js.map +1 -1
  158. package/lib/network/processor/gossipValidatorFn.d.ts +7 -3
  159. package/lib/network/processor/gossipValidatorFn.d.ts.map +1 -1
  160. package/lib/network/processor/gossipValidatorFn.js +7 -3
  161. package/lib/network/processor/gossipValidatorFn.js.map +1 -1
  162. package/lib/network/processor/index.d.ts +9 -0
  163. package/lib/network/processor/index.d.ts.map +1 -1
  164. package/lib/network/processor/index.js +77 -10
  165. package/lib/network/processor/index.js.map +1 -1
  166. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts.map +1 -1
  167. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +41 -26
  168. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
  169. package/lib/node/nodejs.d.ts.map +1 -1
  170. package/lib/node/nodejs.js +25 -3
  171. package/lib/node/nodejs.js.map +1 -1
  172. package/lib/sync/range/batch.d.ts +6 -0
  173. package/lib/sync/range/batch.d.ts.map +1 -1
  174. package/lib/sync/range/batch.js +10 -0
  175. package/lib/sync/range/batch.js.map +1 -1
  176. package/lib/sync/range/chain.d.ts.map +1 -1
  177. package/lib/sync/range/chain.js +5 -1
  178. package/lib/sync/range/chain.js.map +1 -1
  179. package/lib/sync/range/range.d.ts.map +1 -1
  180. package/lib/sync/range/range.js +50 -18
  181. package/lib/sync/range/range.js.map +1 -1
  182. package/lib/sync/unknownBlock.d.ts +9 -5
  183. package/lib/sync/unknownBlock.d.ts.map +1 -1
  184. package/lib/sync/unknownBlock.js +88 -46
  185. package/lib/sync/unknownBlock.js.map +1 -1
  186. package/lib/util/execution.d.ts +11 -11
  187. package/lib/util/execution.d.ts.map +1 -1
  188. package/lib/util/execution.js +6 -2
  189. package/lib/util/execution.js.map +1 -1
  190. package/package.json +16 -16
  191. package/src/api/impl/beacon/blocks/index.ts +7 -4
  192. package/src/api/impl/beacon/index.ts +15 -0
  193. package/src/api/impl/beacon/pool/index.ts +4 -4
  194. package/src/api/impl/validator/index.ts +16 -2
  195. package/src/chain/archiveStore/archiveStore.ts +10 -4
  196. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +5 -7
  197. package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +1 -1
  198. package/src/chain/archiveStore/historicalState/types.ts +2 -2
  199. package/src/chain/archiveStore/historicalState/worker.ts +1 -2
  200. package/src/chain/archiveStore/interface.ts +1 -1
  201. package/src/chain/archiveStore/utils/pruneHistory.ts +6 -4
  202. package/src/chain/blocks/importBlock.ts +4 -0
  203. package/src/chain/blocks/payloadEnvelopeInput/types.ts +2 -1
  204. package/src/chain/blocks/verifyBlock.ts +1 -0
  205. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +6 -3
  206. package/src/chain/chain.ts +50 -19
  207. package/src/chain/emitter.ts +7 -1
  208. package/src/chain/errors/envelopeReconstructionError.ts +3 -0
  209. package/src/chain/errors/gossipValidation.ts +2 -0
  210. package/src/chain/forkChoice/index.ts +2 -0
  211. package/src/chain/initState.ts +8 -60
  212. package/src/chain/interface.ts +2 -2
  213. package/src/chain/opPools/opPool.ts +91 -18
  214. package/src/chain/opPools/proposerPreferencesPool.ts +14 -10
  215. package/src/chain/opPools/utils.ts +31 -3
  216. package/src/chain/options.ts +2 -2
  217. package/src/chain/prepareNextSlot.ts +6 -3
  218. package/src/chain/produceBlock/computeNewStateRoot.ts +1 -1
  219. package/src/chain/produceBlock/produceBlockBody.ts +8 -1
  220. package/src/chain/regen/regen.ts +12 -4
  221. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +31 -13
  222. package/src/chain/validation/attesterSlashing.ts +7 -4
  223. package/src/chain/validation/proposerSlashing.ts +7 -4
  224. package/src/chain/validatorMonitor.ts +75 -57
  225. package/src/db/beacon.ts +2 -0
  226. package/src/db/repositories/proposerSlashing.ts +6 -1
  227. package/src/execution/engine/disabled.ts +0 -8
  228. package/src/execution/engine/http.ts +1 -30
  229. package/src/execution/engine/interface.ts +2 -6
  230. package/src/execution/engine/mock.ts +1 -19
  231. package/src/execution/engine/types.ts +0 -10
  232. package/src/index.ts +1 -1
  233. package/src/metrics/metrics.ts +21 -6
  234. package/src/network/metadata.ts +17 -17
  235. package/src/network/peers/datastore.ts +36 -36
  236. package/src/network/processor/gossipHandlers.ts +7 -4
  237. package/src/network/processor/gossipValidatorFn.ts +13 -3
  238. package/src/network/processor/index.ts +89 -10
  239. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +42 -28
  240. package/src/node/nodejs.ts +31 -3
  241. package/src/sync/range/batch.ts +11 -0
  242. package/src/sync/range/chain.ts +6 -1
  243. package/src/sync/range/range.ts +50 -18
  244. package/src/sync/unknownBlock.ts +99 -50
  245. package/src/util/execution.ts +17 -9
@@ -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
@@ -122,6 +122,8 @@ export class BeaconDb implements IBeaconDb {
122
122
  async pruneHotDb(): Promise<void> {
123
123
  // Prune all hot blobs
124
124
  await this.blobSidecars.batchDelete(await this.blobSidecars.keys());
125
+ // New columns are persisted in flat files, so this bucket only contains legacy hot data.
126
+ await this.deleteBucketData(Bucket.allForks_dataColumnSidecars);
125
127
  // Prune all hot blocks
126
128
  // TODO: Enable once it's deemed safe
127
129
  // await this.block.batchDelete(await this.block.keys());
@@ -1,6 +1,7 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
- import {Db, Repository} from "@lodestar/db";
2
+ import {BUCKET_LENGTH, Db, Repository} from "@lodestar/db";
3
3
  import {ValidatorIndex, phase0, ssz} from "@lodestar/types";
4
+ import {bytesToInt} from "@lodestar/utils";
4
5
  import {Bucket, getBucketNameByValue} from "../buckets.js";
5
6
 
6
7
  export class ProposerSlashingRepository extends Repository<ValidatorIndex, phase0.ProposerSlashing> {
@@ -12,4 +13,8 @@ export class ProposerSlashingRepository extends Repository<ValidatorIndex, phase
12
13
  getId(value: phase0.ProposerSlashing): ValidatorIndex {
13
14
  return value.signedHeader1.message.proposerIndex;
14
15
  }
16
+
17
+ decodeKey(data: Uint8Array): ValidatorIndex {
18
+ return bytesToInt(data.subarray(BUCKET_LENGTH), "be");
19
+ }
15
20
  }
@@ -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)[];
package/src/index.ts CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  export type {RestApiServerMetrics, RestApiServerModules, RestApiServerOpts} from "./api/rest/base.js";
4
4
  export {RestApiServer} from "./api/rest/base.js";
5
- export {checkAndPersistAnchorState} from "./chain/index.js";
5
+ export {persistAnchorState} from "./chain/index.js";
6
6
  export {DbCPStateDatastore} from "./chain/stateCache/datastore/db.js";
7
7
  export {FileCPStateDatastore} from "./chain/stateCache/datastore/file.js";
8
8
  export {BeaconDb, type IBeaconDb} from "./db/index.js";
@@ -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
  };
@@ -42,13 +42,13 @@ export class MetadataController {
42
42
  private onSetValue: (key: string, value: Uint8Array) => void;
43
43
  private networkConfig: NetworkConfig;
44
44
  private logger: Logger;
45
- private _metadata: fulu.Metadata;
45
+ private metadata: fulu.Metadata;
46
46
 
47
47
  constructor(opts: MetadataOpts, modules: MetadataModules) {
48
48
  this.networkConfig = modules.networkConfig;
49
49
  this.logger = modules.logger;
50
50
  this.onSetValue = modules.onSetValue;
51
- this._metadata = opts.metadata ?? {
51
+ this.metadata = opts.metadata ?? {
52
52
  ...ssz.fulu.Metadata.defaultValue(),
53
53
  custodyGroupCount: modules.networkConfig.custodyConfig.targetCustodyGroupCount,
54
54
  };
@@ -58,61 +58,61 @@ export class MetadataController {
58
58
  // updateEth2Field() MUST be called with clock epoch
59
59
  this.updateEth2Field(currentEpoch);
60
60
 
61
- this.onSetValue(ENRKey.attnets, ssz.phase0.AttestationSubnets.serialize(this._metadata.attnets));
61
+ this.onSetValue(ENRKey.attnets, ssz.phase0.AttestationSubnets.serialize(this.metadata.attnets));
62
62
 
63
63
  const config = this.networkConfig.config;
64
64
 
65
65
  if (config.getForkSeq(computeStartSlotAtEpoch(currentEpoch)) >= ForkSeq.altair) {
66
66
  // Only persist syncnets if altair fork is already activated. If currentFork is altair but head is phase0
67
67
  // adding syncnets to the ENR is not a problem, we will just have a useless field for a few hours.
68
- this.onSetValue(ENRKey.syncnets, ssz.altair.SyncSubnets.serialize(this._metadata.syncnets));
68
+ this.onSetValue(ENRKey.syncnets, ssz.altair.SyncSubnets.serialize(this.metadata.syncnets));
69
69
  }
70
70
 
71
71
  // Set CGC regardless of fork. It may be useful to clients before Fulu, and will be ignored otherwise.
72
- this.onSetValue(ENRKey.cgc, serializeCgc(this._metadata.custodyGroupCount));
72
+ this.onSetValue(ENRKey.cgc, serializeCgc(this.metadata.custodyGroupCount));
73
73
  }
74
74
 
75
75
  get seqNumber(): bigint {
76
- return this._metadata.seqNumber;
76
+ return this.metadata.seqNumber;
77
77
  }
78
78
 
79
79
  get syncnets(): BitArray {
80
- return this._metadata.syncnets;
80
+ return this.metadata.syncnets;
81
81
  }
82
82
 
83
83
  set syncnets(syncnets: BitArray) {
84
84
  this.onSetValue(ENRKey.syncnets, ssz.altair.SyncSubnets.serialize(syncnets));
85
- this._metadata.seqNumber++;
86
- this._metadata.syncnets = syncnets;
85
+ this.metadata.seqNumber++;
86
+ this.metadata.syncnets = syncnets;
87
87
  }
88
88
 
89
89
  get attnets(): BitArray {
90
- return this._metadata.attnets;
90
+ return this.metadata.attnets;
91
91
  }
92
92
 
93
93
  set attnets(attnets: BitArray) {
94
94
  this.onSetValue(ENRKey.attnets, ssz.phase0.AttestationSubnets.serialize(attnets));
95
- this._metadata.seqNumber++;
96
- this._metadata.attnets = attnets;
95
+ this.metadata.seqNumber++;
96
+ this.metadata.attnets = attnets;
97
97
  }
98
98
 
99
99
  get custodyGroupCount(): number {
100
- return this._metadata.custodyGroupCount;
100
+ return this.metadata.custodyGroupCount;
101
101
  }
102
102
 
103
103
  set custodyGroupCount(custodyGroupCount: number) {
104
- if (custodyGroupCount === this._metadata.custodyGroupCount) {
104
+ if (custodyGroupCount === this.metadata.custodyGroupCount) {
105
105
  return;
106
106
  }
107
107
  this.onSetValue(ENRKey.cgc, serializeCgc(custodyGroupCount));
108
108
  this.logger.debug("Updated cgc field in ENR", {custodyGroupCount});
109
- this._metadata.seqNumber++;
110
- this._metadata.custodyGroupCount = custodyGroupCount;
109
+ this.metadata.seqNumber++;
110
+ this.metadata.custodyGroupCount = custodyGroupCount;
111
111
  }
112
112
 
113
113
  /** Consumers that need the phase0.Metadata type can just ignore the .syncnets property */
114
114
  get json(): fulu.Metadata {
115
- return this._metadata;
115
+ return this.metadata;
116
116
  }
117
117
 
118
118
  /**