@lodestar/beacon-node 1.35.0-dev.21ba2777a9 → 1.35.0-dev.248b252a94

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 (107) hide show
  1. package/lib/api/impl/beacon/blocks/index.js +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  3. package/lib/api/impl/lodestar/index.js +1 -1
  4. package/lib/api/impl/lodestar/index.js.map +1 -1
  5. package/lib/api/impl/validator/index.d.ts.map +1 -1
  6. package/lib/api/impl/validator/index.js +20 -25
  7. package/lib/api/impl/validator/index.js.map +1 -1
  8. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  9. package/lib/chain/blocks/blockInput/blockInput.js +1 -1
  10. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  11. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  12. package/lib/chain/blocks/importBlock.js +7 -6
  13. package/lib/chain/blocks/importBlock.js.map +1 -1
  14. package/lib/chain/blocks/verifyBlocksDataAvailability.d.ts.map +1 -1
  15. package/lib/chain/blocks/verifyBlocksDataAvailability.js +8 -1
  16. package/lib/chain/blocks/verifyBlocksDataAvailability.js.map +1 -1
  17. package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
  18. package/lib/chain/blocks/writeBlockInputToDb.js +1 -7
  19. package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
  20. package/lib/chain/chain.d.ts.map +1 -1
  21. package/lib/chain/chain.js +3 -4
  22. package/lib/chain/chain.js.map +1 -1
  23. package/lib/chain/opPools/attestationPool.d.ts +2 -3
  24. package/lib/chain/opPools/attestationPool.d.ts.map +1 -1
  25. package/lib/chain/opPools/attestationPool.js +3 -5
  26. package/lib/chain/opPools/attestationPool.js.map +1 -1
  27. package/lib/chain/opPools/syncCommitteeMessagePool.d.ts +3 -2
  28. package/lib/chain/opPools/syncCommitteeMessagePool.d.ts.map +1 -1
  29. package/lib/chain/opPools/syncCommitteeMessagePool.js +6 -5
  30. package/lib/chain/opPools/syncCommitteeMessagePool.js.map +1 -1
  31. package/lib/chain/opPools/types.d.ts +1 -1
  32. package/lib/chain/opPools/types.d.ts.map +1 -1
  33. package/lib/chain/opPools/types.js +1 -1
  34. package/lib/chain/opPools/types.js.map +1 -1
  35. package/lib/chain/prepareNextSlot.d.ts +3 -3
  36. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  37. package/lib/chain/prepareNextSlot.js +8 -8
  38. package/lib/chain/prepareNextSlot.js.map +1 -1
  39. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  40. package/lib/chain/stateCache/persistentCheckpointsCache.js +9 -8
  41. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  42. package/lib/chain/validation/lightClientFinalityUpdate.d.ts.map +1 -1
  43. package/lib/chain/validation/lightClientFinalityUpdate.js +4 -3
  44. package/lib/chain/validation/lightClientFinalityUpdate.js.map +1 -1
  45. package/lib/chain/validation/lightClientOptimisticUpdate.d.ts +6 -4
  46. package/lib/chain/validation/lightClientOptimisticUpdate.d.ts.map +1 -1
  47. package/lib/chain/validation/lightClientOptimisticUpdate.js +11 -11
  48. package/lib/chain/validation/lightClientOptimisticUpdate.js.map +1 -1
  49. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  50. package/lib/chain/validatorMonitor.js +21 -15
  51. package/lib/chain/validatorMonitor.js.map +1 -1
  52. package/lib/metrics/metrics/lodestar.d.ts +1 -1
  53. package/lib/metrics/metrics/lodestar.js +3 -3
  54. package/lib/metrics/metrics/lodestar.js.map +1 -1
  55. package/lib/network/gossip/gossipsub.js +1 -1
  56. package/lib/network/gossip/gossipsub.js.map +1 -1
  57. package/lib/network/gossip/scoringParameters.js +4 -4
  58. package/lib/network/gossip/scoringParameters.js.map +1 -1
  59. package/lib/network/network.d.ts +1 -1
  60. package/lib/network/network.d.ts.map +1 -1
  61. package/lib/network/network.js +9 -9
  62. package/lib/network/network.js.map +1 -1
  63. package/lib/network/peers/peerManager.d.ts.map +1 -1
  64. package/lib/network/peers/peerManager.js +2 -1
  65. package/lib/network/peers/peerManager.js.map +1 -1
  66. package/lib/network/processor/gossipHandlers.js +1 -1
  67. package/lib/network/processor/gossipHandlers.js.map +1 -1
  68. package/lib/network/subnets/attnetsService.d.ts.map +1 -1
  69. package/lib/network/subnets/attnetsService.js +1 -1
  70. package/lib/network/subnets/attnetsService.js.map +1 -1
  71. package/lib/node/notifier.js +1 -1
  72. package/lib/node/notifier.js.map +1 -1
  73. package/lib/sync/unknownBlock.d.ts +0 -1
  74. package/lib/sync/unknownBlock.d.ts.map +1 -1
  75. package/lib/sync/unknownBlock.js +7 -6
  76. package/lib/sync/unknownBlock.js.map +1 -1
  77. package/lib/util/clock.d.ts +8 -3
  78. package/lib/util/clock.d.ts.map +1 -1
  79. package/lib/util/clock.js +8 -5
  80. package/lib/util/clock.js.map +1 -1
  81. package/package.json +14 -14
  82. package/src/api/impl/beacon/blocks/index.ts +1 -1
  83. package/src/api/impl/lodestar/index.ts +1 -1
  84. package/src/api/impl/validator/index.ts +21 -26
  85. package/src/chain/blocks/blockInput/blockInput.ts +2 -1
  86. package/src/chain/blocks/importBlock.ts +8 -12
  87. package/src/chain/blocks/verifyBlocksDataAvailability.ts +10 -2
  88. package/src/chain/blocks/writeBlockInputToDb.ts +1 -9
  89. package/src/chain/chain.ts +3 -14
  90. package/src/chain/opPools/attestationPool.ts +2 -3
  91. package/src/chain/opPools/syncCommitteeMessagePool.ts +5 -3
  92. package/src/chain/opPools/types.ts +1 -1
  93. package/src/chain/prepareNextSlot.ts +8 -8
  94. package/src/chain/stateCache/persistentCheckpointsCache.ts +10 -8
  95. package/src/chain/validation/lightClientFinalityUpdate.ts +4 -3
  96. package/src/chain/validation/lightClientOptimisticUpdate.ts +12 -11
  97. package/src/chain/validatorMonitor.ts +28 -17
  98. package/src/metrics/metrics/lodestar.ts +3 -3
  99. package/src/network/gossip/gossipsub.ts +1 -1
  100. package/src/network/gossip/scoringParameters.ts +4 -4
  101. package/src/network/network.ts +9 -9
  102. package/src/network/peers/peerManager.ts +2 -1
  103. package/src/network/processor/gossipHandlers.ts +1 -1
  104. package/src/network/subnets/attnetsService.ts +3 -6
  105. package/src/node/notifier.ts +1 -1
  106. package/src/sync/unknownBlock.ts +7 -6
  107. package/src/util/clock.ts +14 -6
@@ -84,10 +84,10 @@ export function computeGossipPeerScoreParams({
84
84
  config: BeaconConfig;
85
85
  eth2Context: Eth2Context;
86
86
  }): Partial<PeerScoreParams> {
87
- const decayIntervalMs = config.SECONDS_PER_SLOT * 1000;
87
+ const decayIntervalMs = config.SLOT_DURATION_MS;
88
88
  const decayToZero = 0.01;
89
- const epochDurationMs = config.SECONDS_PER_SLOT * SLOTS_PER_EPOCH * 1000;
90
- const slotDurationMs = config.SECONDS_PER_SLOT * 1000;
89
+ const epochDurationMs = config.SLOT_DURATION_MS * SLOTS_PER_EPOCH;
90
+ const slotDurationMs = config.SLOT_DURATION_MS;
91
91
  const scoreParameterDecayFn = (decayTimeMs: number): number => {
92
92
  return scoreParameterDecayWithBase(decayTimeMs, decayIntervalMs, decayToZero);
93
93
  };
@@ -265,7 +265,7 @@ function getTopicScoreParams(
265
265
 
266
266
  if (meshMessageInfo) {
267
267
  const {decaySlots, capFactor, activationWindow, currentSlot} = meshMessageInfo;
268
- const decayTimeMs = config.SECONDS_PER_SLOT * decaySlots * 1000;
268
+ const decayTimeMs = config.SLOT_DURATION_MS * decaySlots;
269
269
  params.meshMessageDeliveriesDecay = scoreParameterDecayFn(decayTimeMs);
270
270
  params.meshMessageDeliveriesThreshold = threshold(params.meshMessageDeliveriesDecay, expectedMessageRate / 50);
271
271
  params.meshMessageDeliveriesCap = Math.max(capFactor * params.meshMessageDeliveriesThreshold, 2);
@@ -7,7 +7,7 @@ import {BeaconConfig} from "@lodestar/config";
7
7
  import {LoggerNode} from "@lodestar/logger/node";
8
8
  import {ForkSeq} from "@lodestar/params";
9
9
  import {ResponseIncoming} from "@lodestar/reqresp";
10
- import {computeEpochAtSlot, computeTimeAtSlot} from "@lodestar/state-transition";
10
+ import {computeEpochAtSlot} from "@lodestar/state-transition";
11
11
  import {
12
12
  AttesterSlashing,
13
13
  LightClientBootstrap,
@@ -689,9 +689,9 @@ export class Network implements INetwork {
689
689
  // TODO: Review is OK to remove if (this.hasAttachedSyncCommitteeMember())
690
690
 
691
691
  try {
692
- // messages SHOULD be broadcast after one-third of slot has transpired
692
+ // messages SHOULD be broadcast after SYNC_MESSAGE_DUE_BPS of slot has transpired
693
693
  // https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/p2p-interface.md#sync-committee
694
- await this.waitOneThirdOfSlot(finalityUpdate.signatureSlot);
694
+ await this.waitForSyncMessageCutoff(finalityUpdate.signatureSlot);
695
695
  await this.publishLightClientFinalityUpdate(finalityUpdate);
696
696
  } catch (e) {
697
697
  // Non-mandatory route on most of network as of Oct 2022. May not have found any peers on topic yet
@@ -706,9 +706,9 @@ export class Network implements INetwork {
706
706
  // TODO: Review is OK to remove if (this.hasAttachedSyncCommitteeMember())
707
707
 
708
708
  try {
709
- // messages SHOULD be broadcast after one-third of slot has transpired
709
+ // messages SHOULD be broadcast after SYNC_MESSAGE_DUE_BPS of slot has transpired
710
710
  // https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/p2p-interface.md#sync-committee
711
- await this.waitOneThirdOfSlot(optimisticUpdate.signatureSlot);
711
+ await this.waitForSyncMessageCutoff(optimisticUpdate.signatureSlot);
712
712
  await this.publishLightClientOptimisticUpdate(optimisticUpdate);
713
713
  } catch (e) {
714
714
  // Non-mandatory route on most of network as of Oct 2022. May not have found any peers on topic yet
@@ -719,10 +719,10 @@ export class Network implements INetwork {
719
719
  }
720
720
  };
721
721
 
722
- private waitOneThirdOfSlot = async (slot: number): Promise<void> => {
723
- const secAtSlot = computeTimeAtSlot(this.config, slot + 1 / 3, this.chain.genesisTime);
724
- const msToSlot = secAtSlot * 1000 - Date.now();
725
- await sleep(msToSlot, this.controller.signal);
722
+ private waitForSyncMessageCutoff = async (slot: number): Promise<void> => {
723
+ const fork = this.config.getForkName(slot);
724
+ const msToCutoffTime = this.config.getSyncMessageDueMs(fork) - this.chain.clock.msFromSlot(slot);
725
+ await sleep(msToCutoffTime, this.controller.signal);
726
726
  };
727
727
 
728
728
  private onHead = async (): Promise<void> => {
@@ -3,6 +3,7 @@ import {BitArray} from "@chainsafe/ssz";
3
3
  import {BeaconConfig} from "@lodestar/config";
4
4
  import {LoggerNode} from "@lodestar/logger/node";
5
5
  import {ForkSeq, SLOTS_PER_EPOCH, SYNC_COMMITTEE_SUBNET_COUNT} from "@lodestar/params";
6
+ import {computeTimeAtSlot} from "@lodestar/state-transition";
6
7
  import {Metadata, Status, altair, fulu, phase0} from "@lodestar/types";
7
8
  import {prettyPrintIndices, toHex, withTimeout} from "@lodestar/utils";
8
9
  import {GOODBYE_KNOWN_CODES, GoodByeReasonCode, Libp2pEvent} from "../../constants/index.js";
@@ -599,7 +600,7 @@ export class PeerManager {
599
600
  subnet: query.subnet,
600
601
  type,
601
602
  maxPeersToDiscover: query.maxPeersToDiscover,
602
- toUnixMs: 1000 * (this.clock.genesisTime + query.toSlot * this.config.SECONDS_PER_SLOT),
603
+ toUnixMs: computeTimeAtSlot(this.config, query.toSlot, this.clock.genesisTime) * 1000,
603
604
  });
604
605
  }
605
606
 
@@ -379,7 +379,7 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
379
379
 
380
380
  // Handler - MUST NOT `await`, to allow validation result to be propagated
381
381
 
382
- const delaySec = seenTimestampSec - (chain.genesisTime + slot * config.SECONDS_PER_SLOT);
382
+ const delaySec = seenTimestampSec - computeTimeAtSlot(config, slot, chain.genesisTime);
383
383
  metrics?.gossipBlock.elapsedTimeTillReceived.observe({source: OpSource.gossip}, delaySec);
384
384
  chain.validatorMonitor?.registerBeaconBlock(OpSource.gossip, delaySec, signedBlock.message);
385
385
  if (!blockInput.hasBlockAndAllData()) {
@@ -163,12 +163,9 @@ export class AttnetsService implements IAttnetsService {
163
163
  */
164
164
  private onSlot = (clockSlot: Slot): void => {
165
165
  try {
166
- setTimeout(
167
- () => {
168
- this.onHalfSlot(clockSlot);
169
- },
170
- this.config.SECONDS_PER_SLOT * 0.5 * 1000
171
- );
166
+ setTimeout(() => {
167
+ this.onHalfSlot(clockSlot);
168
+ }, this.config.SLOT_DURATION_MS * 0.5);
172
169
 
173
170
  for (const [dutiedSlot, dutiedInfo] of this.aggregatorSlotSubnet.entries()) {
174
171
  if (dutiedSlot === clockSlot + this.opts.slotsToSubscribeBeforeAggregatorDuty) {
@@ -157,7 +157,7 @@ export async function runNodeNotifier(modules: NodeNotifierModules): Promise<voi
157
157
  }
158
158
 
159
159
  function timeToNextHalfSlot(config: BeaconConfig, chain: IBeaconChain, isFirstTime: boolean): number {
160
- const msPerSlot = config.SECONDS_PER_SLOT * 1000;
160
+ const msPerSlot = config.SLOT_DURATION_MS;
161
161
  const msPerHalfSlot = msPerSlot / 2;
162
162
  const msFromGenesis = Date.now() - chain.genesisTime * 1000;
163
163
  const msToNextSlot =
@@ -1,6 +1,7 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
- import {ForkSeq, INTERVALS_PER_SLOT} from "@lodestar/params";
2
+ import {ForkSeq} from "@lodestar/params";
3
3
  import {RequestError, RequestErrorCode} from "@lodestar/reqresp";
4
+ import {computeTimeAtSlot} from "@lodestar/state-transition";
4
5
  import {RootHex} from "@lodestar/types";
5
6
  import {Logger, prettyPrintIndices, pruneSetToMax, sleep} from "@lodestar/utils";
6
7
  import {isBlockInputBlobs, isBlockInputColumns} from "../chain/blocks/blockInput/blockInput.js";
@@ -78,7 +79,6 @@ export class BlockInputSync {
78
79
  */
79
80
  private readonly pendingBlocks = new Map<RootHex, BlockInputSyncCacheItem>();
80
81
  private readonly knownBadBlocks = new Set<RootHex>();
81
- private readonly proposerBoostSecWindow: number;
82
82
  private readonly maxPendingBlocks;
83
83
  private subscribedToNetworkEvents = false;
84
84
  private peerBalancer: UnknownBlockPeerBalancer;
@@ -92,7 +92,6 @@ export class BlockInputSync {
92
92
  private readonly opts?: SyncOptions
93
93
  ) {
94
94
  this.maxPendingBlocks = opts?.maxPendingBlocks ?? MAX_PENDING_BLOCKS;
95
- this.proposerBoostSecWindow = this.config.SECONDS_PER_SLOT / INTERVALS_PER_SLOT;
96
95
  this.peerBalancer = new UnknownBlockPeerBalancer();
97
96
 
98
97
  if (metrics) {
@@ -331,7 +330,7 @@ export class BlockInputSync {
331
330
  this.pendingBlocks.set(pending.blockInput.blockRootHex, pending);
332
331
  const blockSlot = pending.blockInput.slot;
333
332
  const finalizedSlot = this.chain.forkChoice.getFinalizedBlock().slot;
334
- const delaySec = Date.now() / 1000 - (this.chain.genesisTime + blockSlot * this.config.SECONDS_PER_SLOT);
333
+ const delaySec = Date.now() / 1000 - computeTimeAtSlot(this.config, blockSlot, this.chain.genesisTime);
335
334
  this.metrics?.blockInputSync.elapsedTimeTillReceived.observe(delaySec);
336
335
 
337
336
  const parentInForkChoice = this.chain.forkChoice.hasBlockHex(pending.blockInput.parentRootHex);
@@ -396,8 +395,10 @@ export class BlockInputSync {
396
395
  // this prevents unbundling attack
397
396
  // see https://lighthouse-blog.sigmaprime.io/mev-unbundling-rpc.html
398
397
  const {slot: blockSlot, proposerIndex} = pendingBlock.blockInput.getBlock().message;
398
+ const fork = this.config.getForkName(blockSlot);
399
+ const proposerBoostWindowMs = this.config.getAttestationDueMs(fork);
399
400
  if (
400
- this.chain.clock.secFromSlot(blockSlot) < this.proposerBoostSecWindow &&
401
+ this.chain.clock.msFromSlot(blockSlot) < proposerBoostWindowMs &&
401
402
  this.chain.seenBlockProposers.isKnown(blockSlot, proposerIndex)
402
403
  ) {
403
404
  // proposer is known by a gossip block already, wait a bit to make sure this block is not
@@ -407,7 +408,7 @@ export class BlockInputSync {
407
408
  root: pendingBlock.blockInput.blockRootHex,
408
409
  proposerIndex,
409
410
  });
410
- await sleep(this.proposerBoostSecWindow * 1000);
411
+ await sleep(proposerBoostWindowMs);
411
412
  }
412
413
  // At gossip time, it's critical to keep a good number of mesh peers.
413
414
  // To do that, the Gossip Job Wait Time should be consistently <3s to avoid the behavior penalties in gossip
package/src/util/clock.ts CHANGED
@@ -9,12 +9,12 @@ import {MAXIMUM_GOSSIP_CLOCK_DISPARITY} from "../constants/constants.js";
9
9
  export enum ClockEvent {
10
10
  /**
11
11
  * This event signals the start of a new slot, and that subsequent calls to `clock.currentSlot` will equal `slot`.
12
- * This event is guaranteed to be emitted every `SECONDS_PER_SLOT` seconds.
12
+ * This event is guaranteed to be emitted every `SLOT_DURATION_MS` milliseconds.
13
13
  */
14
14
  slot = "clock:slot",
15
15
  /**
16
16
  * This event signals the start of a new epoch, and that subsequent calls to `clock.currentEpoch` will return `epoch`.
17
- * This event is guaranteed to be emitted every `SECONDS_PER_SLOT * SLOTS_PER_EPOCH` seconds.
17
+ * This event is guaranteed to be emitted every `SLOT_DURATION_MS * SLOTS_PER_EPOCH` milliseconds.
18
18
  */
19
19
  epoch = "clock:epoch",
20
20
  }
@@ -29,7 +29,7 @@ export type ClockEvents = {
29
29
  *
30
30
  * The time is dependent on:
31
31
  * - `state.genesisTime` - the genesis time
32
- * - `SECONDS_PER_SLOT` - # of seconds per slot
32
+ * - `SLOT_DURATION_MS` - # of milliseconds per slot
33
33
  * - `SLOTS_PER_EPOCH` - # of slots per epoch
34
34
  */
35
35
  export type IClock = StrictEventEmitter<EventEmitter, ClockEvents> & {
@@ -58,6 +58,10 @@ export type IClock = StrictEventEmitter<EventEmitter, ClockEvents> & {
58
58
  * Return second from a slot to either toSec or now.
59
59
  */
60
60
  secFromSlot(slot: Slot, toSec?: number): number;
61
+ /**
62
+ * Return milliseconds from a slot to either toMs or now.
63
+ */
64
+ msFromSlot(slot: Slot, toMs?: number): number;
61
65
  };
62
66
 
63
67
  /**
@@ -170,12 +174,16 @@ export class Clock extends EventEmitter implements IClock {
170
174
  }
171
175
 
172
176
  secFromSlot(slot: Slot, toSec = Date.now() / 1000): number {
173
- return toSec - (this.genesisTime + slot * this.config.SECONDS_PER_SLOT);
177
+ return toSec - computeTimeAtSlot(this.config, slot, this.genesisTime);
178
+ }
179
+
180
+ msFromSlot(slot: Slot, toMs = Date.now()): number {
181
+ return toMs - computeTimeAtSlot(this.config, slot, this.genesisTime) * 1000;
174
182
  }
175
183
 
176
184
  private onNextSlot = (slot?: Slot): void => {
177
185
  const clockSlot = slot ?? getCurrentSlot(this.config, this.genesisTime);
178
- // process multiple clock slots in the case the main thread has been saturated for > SECONDS_PER_SLOT
186
+ // process multiple clock slots in the case the main thread has been saturated for > SLOT_DURATION_MS
179
187
  while (this._currentSlot < clockSlot && !this.signal.aborted) {
180
188
  const previousSlot = this._currentSlot;
181
189
  this._currentSlot++;
@@ -197,7 +205,7 @@ export class Clock extends EventEmitter implements IClock {
197
205
  };
198
206
 
199
207
  private msUntilNextSlot(): number {
200
- const milliSecondsPerSlot = this.config.SECONDS_PER_SLOT * 1000;
208
+ const milliSecondsPerSlot = this.config.SLOT_DURATION_MS;
201
209
  const diffInMilliSeconds = Date.now() - this.genesisTime * 1000;
202
210
  return milliSecondsPerSlot - (diffInMilliSeconds % milliSecondsPerSlot);
203
211
  }