@lodestar/beacon-node 1.40.0-dev.7922561845 → 1.40.0-dev.8ed981ca92

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 (101) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +8 -2
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/lodestar/index.d.ts.map +1 -1
  5. package/lib/api/impl/lodestar/index.js +14 -0
  6. package/lib/api/impl/lodestar/index.js.map +1 -1
  7. package/lib/api/rest/base.d.ts.map +1 -1
  8. package/lib/api/rest/base.js +12 -10
  9. package/lib/api/rest/base.js.map +1 -1
  10. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  11. package/lib/chain/archiveStore/archiveStore.js +10 -4
  12. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  13. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  14. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +2 -1
  15. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  16. package/lib/chain/blocks/blockInput/blockInput.js +2 -2
  17. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  18. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  19. package/lib/chain/blocks/importBlock.js +5 -1
  20. package/lib/chain/blocks/importBlock.js.map +1 -1
  21. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  22. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +1 -2
  23. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  24. package/lib/chain/chain.js +1 -1
  25. package/lib/chain/chain.js.map +1 -1
  26. package/lib/chain/initState.d.ts.map +1 -1
  27. package/lib/chain/initState.js +2 -2
  28. package/lib/chain/initState.js.map +1 -1
  29. package/lib/chain/lightClient/index.d.ts +2 -0
  30. package/lib/chain/lightClient/index.d.ts.map +1 -1
  31. package/lib/chain/lightClient/index.js +11 -6
  32. package/lib/chain/lightClient/index.js.map +1 -1
  33. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  34. package/lib/chain/seenCache/seenGossipBlockInput.js +2 -2
  35. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  36. package/lib/chain/serializeState.d.ts.map +1 -1
  37. package/lib/chain/serializeState.js +2 -1
  38. package/lib/chain/serializeState.js.map +1 -1
  39. package/lib/chain/validation/blobSidecar.js +2 -2
  40. package/lib/chain/validation/blobSidecar.js.map +1 -1
  41. package/lib/chain/validation/dataColumnSidecar.js +2 -2
  42. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  43. package/lib/network/core/networkCore.d.ts +3 -0
  44. package/lib/network/core/networkCore.d.ts.map +1 -1
  45. package/lib/network/core/networkCore.js +9 -0
  46. package/lib/network/core/networkCore.js.map +1 -1
  47. package/lib/network/core/networkCoreWorker.js +3 -0
  48. package/lib/network/core/networkCoreWorker.js.map +1 -1
  49. package/lib/network/core/networkCoreWorkerHandler.d.ts +3 -0
  50. package/lib/network/core/networkCoreWorkerHandler.d.ts.map +1 -1
  51. package/lib/network/core/networkCoreWorkerHandler.js +9 -0
  52. package/lib/network/core/networkCoreWorkerHandler.js.map +1 -1
  53. package/lib/network/core/types.d.ts +3 -0
  54. package/lib/network/core/types.d.ts.map +1 -1
  55. package/lib/network/gossip/gossipsub.d.ts +16 -1
  56. package/lib/network/gossip/gossipsub.d.ts.map +1 -1
  57. package/lib/network/gossip/gossipsub.js +52 -0
  58. package/lib/network/gossip/gossipsub.js.map +1 -1
  59. package/lib/network/network.d.ts +3 -0
  60. package/lib/network/network.d.ts.map +1 -1
  61. package/lib/network/network.js +9 -0
  62. package/lib/network/network.js.map +1 -1
  63. package/lib/sync/backfill/backfill.d.ts.map +1 -1
  64. package/lib/sync/backfill/backfill.js +1 -2
  65. package/lib/sync/backfill/backfill.js.map +1 -1
  66. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  67. package/lib/sync/utils/downloadByRange.js +2 -2
  68. package/lib/sync/utils/downloadByRange.js.map +1 -1
  69. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  70. package/lib/sync/utils/downloadByRoot.js +1 -2
  71. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  72. package/package.json +16 -16
  73. package/src/api/impl/beacon/blocks/index.ts +22 -12
  74. package/src/api/impl/lodestar/index.ts +17 -0
  75. package/src/api/rest/base.ts +15 -13
  76. package/src/chain/archiveStore/archiveStore.ts +10 -4
  77. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +2 -1
  78. package/src/chain/blocks/blockInput/blockInput.ts +2 -2
  79. package/src/chain/blocks/importBlock.ts +5 -1
  80. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +1 -2
  81. package/src/chain/chain.ts +1 -1
  82. package/src/chain/initState.ts +2 -2
  83. package/src/chain/lightClient/index.ts +12 -6
  84. package/src/chain/seenCache/seenGossipBlockInput.ts +2 -2
  85. package/src/chain/serializeState.ts +2 -1
  86. package/src/chain/validation/blobSidecar.ts +2 -2
  87. package/src/chain/validation/dataColumnSidecar.ts +2 -2
  88. package/src/network/core/networkCore.ts +12 -0
  89. package/src/network/core/networkCoreWorker.ts +3 -0
  90. package/src/network/core/networkCoreWorkerHandler.ts +9 -0
  91. package/src/network/core/types.ts +6 -0
  92. package/src/network/gossip/gossipsub.ts +62 -1
  93. package/src/network/network.ts +12 -0
  94. package/src/sync/backfill/backfill.ts +1 -2
  95. package/src/sync/utils/downloadByRange.ts +2 -2
  96. package/src/sync/utils/downloadByRoot.ts +1 -2
  97. package/lib/util/bytes.d.ts +0 -3
  98. package/lib/util/bytes.d.ts.map +0 -1
  99. package/lib/util/bytes.js +0 -11
  100. package/lib/util/bytes.js.map +0 -1
  101. package/src/util/bytes.ts +0 -11
@@ -5,6 +5,7 @@ import {GossipSub, GossipsubEvents} from "@chainsafe/libp2p-gossipsub";
5
5
  import {MetricsRegister, TopicLabel, TopicStrToLabel} from "@chainsafe/libp2p-gossipsub/metrics";
6
6
  import {PeerScoreParams} from "@chainsafe/libp2p-gossipsub/score";
7
7
  import {AddrInfo, SignaturePolicy, TopicStr} from "@chainsafe/libp2p-gossipsub/types";
8
+ import {routes} from "@lodestar/api";
8
9
  import {BeaconConfig, ForkBoundary} from "@lodestar/config";
9
10
  import {ATTESTATION_SUBNET_COUNT, SLOTS_PER_EPOCH, SYNC_COMMITTEE_SUBNET_COUNT} from "@lodestar/params";
10
11
  import {SubnetID} from "@lodestar/types";
@@ -87,6 +88,7 @@ export class Eth2Gossipsub extends GossipSub {
87
88
  private readonly logger: Logger;
88
89
  private readonly peersData: PeersData;
89
90
  private readonly events: NetworkEventBus;
91
+ private readonly libp2p: Libp2p;
90
92
 
91
93
  // Internal caches
92
94
  private readonly gossipTopicCache: GossipTopicCache;
@@ -159,6 +161,7 @@ export class Eth2Gossipsub extends GossipSub {
159
161
  this.logger = logger;
160
162
  this.peersData = peersData;
161
163
  this.events = events;
164
+ this.libp2p = modules.libp2p;
162
165
  this.gossipTopicCache = gossipTopicCache;
163
166
 
164
167
  this.addEventListener("gossipsub:message", this.onGossipsubMessage.bind(this));
@@ -341,6 +344,64 @@ export class Eth2Gossipsub extends GossipSub {
341
344
  this.reportMessageValidationResult(data.msgId, data.propagationSource, data.acceptance);
342
345
  });
343
346
  }
347
+
348
+ /**
349
+ * Add a peer as a direct peer at runtime. Accepts multiaddr with peer ID or ENR string.
350
+ * Direct peers maintain permanent mesh connections without GRAFT/PRUNE negotiation.
351
+ */
352
+ async addDirectPeer(peerStr: routes.lodestar.DirectPeer): Promise<string | null> {
353
+ const parsed = parseDirectPeers([peerStr], this.logger);
354
+ if (parsed.length === 0) {
355
+ return null;
356
+ }
357
+
358
+ const {id: peerId, addrs} = parsed[0];
359
+ const peerIdStr = peerId.toString();
360
+
361
+ // Prevent adding self as a direct peer
362
+ if (peerId.equals(this.libp2p.peerId)) {
363
+ this.logger.warn("Cannot add self as a direct peer", {peerId: peerIdStr});
364
+ return null;
365
+ }
366
+
367
+ // Direct peers need addresses to connect - reject if none provided
368
+ if (addrs.length === 0) {
369
+ this.logger.warn("Cannot add direct peer without addresses", {peerId: peerIdStr});
370
+ return null;
371
+ }
372
+
373
+ // Add addresses to peer store first so we can connect
374
+ try {
375
+ await this.libp2p.peerStore.merge(peerId, {multiaddrs: addrs});
376
+ } catch (e) {
377
+ this.logger.warn("Failed to add direct peer addresses to peer store", {peerId: peerIdStr}, e as Error);
378
+ return null;
379
+ }
380
+
381
+ // Add to direct peers set only after addresses are stored
382
+ this.direct.add(peerIdStr);
383
+
384
+ this.logger.info("Added direct peer via API", {peerId: peerIdStr});
385
+ return peerIdStr;
386
+ }
387
+
388
+ /**
389
+ * Remove a peer from direct peers.
390
+ */
391
+ removeDirectPeer(peerIdStr: string): boolean {
392
+ const removed = this.direct.delete(peerIdStr);
393
+ if (removed) {
394
+ this.logger.info("Removed direct peer via API", {peerId: peerIdStr});
395
+ }
396
+ return removed;
397
+ }
398
+
399
+ /**
400
+ * Get list of current direct peer IDs.
401
+ */
402
+ getDirectPeers(): string[] {
403
+ return Array.from(this.direct);
404
+ }
344
405
  }
345
406
 
346
407
  /**
@@ -406,7 +467,7 @@ function getForkBoundaryLabel(boundary: ForkBoundary): ForkBoundaryLabel {
406
467
  * For multiaddrs, the string must contain a /p2p/ component with the peer ID.
407
468
  * For ENRs, the TCP multiaddr and peer ID are extracted from the encoded record.
408
469
  */
409
- export function parseDirectPeers(directPeerStrs: string[], logger: Logger): AddrInfo[] {
470
+ export function parseDirectPeers(directPeerStrs: routes.lodestar.DirectPeer[], logger: Logger): AddrInfo[] {
410
471
  const directPeers: AddrInfo[] = [];
411
472
 
412
473
  for (const peerStr of directPeerStrs) {
@@ -641,6 +641,18 @@ export class Network implements INetwork {
641
641
  return this.core.disconnectPeer(peer);
642
642
  }
643
643
 
644
+ addDirectPeer(peer: routes.lodestar.DirectPeer): Promise<string | null> {
645
+ return this.core.addDirectPeer(peer);
646
+ }
647
+
648
+ removeDirectPeer(peerId: string): Promise<boolean> {
649
+ return this.core.removeDirectPeer(peerId);
650
+ }
651
+
652
+ getDirectPeers(): Promise<string[]> {
653
+ return this.core.getDirectPeers();
654
+ }
655
+
644
656
  dumpPeer(peerIdStr: string): Promise<routes.lodestar.LodestarNodePeer | undefined> {
645
657
  return this.core.dumpPeer(peerIdStr);
646
658
  }
@@ -4,13 +4,12 @@ import {BeaconConfig, ChainForkConfig} from "@lodestar/config";
4
4
  import {SLOTS_PER_EPOCH} from "@lodestar/params";
5
5
  import {BeaconStateAllForks, blockToHeader, computeAnchorCheckpoint} from "@lodestar/state-transition";
6
6
  import {Root, SignedBeaconBlock, Slot, phase0, ssz} from "@lodestar/types";
7
- import {ErrorAborted, Logger, sleep, toRootHex} from "@lodestar/utils";
7
+ import {ErrorAborted, Logger, byteArrayEquals, sleep, toRootHex} from "@lodestar/utils";
8
8
  import {IBeaconChain} from "../../chain/index.js";
9
9
  import {GENESIS_SLOT, ZERO_HASH} from "../../constants/index.js";
10
10
  import {IBeaconDb} from "../../db/index.js";
11
11
  import {Metrics} from "../../metrics/metrics.js";
12
12
  import {INetwork, NetworkEvent, NetworkEventData, PeerAction} from "../../network/index.js";
13
- import {byteArrayEquals} from "../../util/bytes.js";
14
13
  import {ItTrigger} from "../../util/itTrigger.js";
15
14
  import {PeerIdStr} from "../../util/peerId.js";
16
15
  import {shuffleOne} from "../../util/shuffle.js";
@@ -8,7 +8,7 @@ import {
8
8
  isForkPostGloas,
9
9
  } from "@lodestar/params";
10
10
  import {SignedBeaconBlock, Slot, deneb, fulu, phase0} from "@lodestar/types";
11
- import {LodestarError, Logger, fromHex, prettyPrintIndices, toRootHex} from "@lodestar/utils";
11
+ import {LodestarError, Logger, byteArrayEquals, fromHex, prettyPrintIndices, toRootHex} from "@lodestar/utils";
12
12
  import {
13
13
  BlockInputSource,
14
14
  DAType,
@@ -475,7 +475,7 @@ export function validateBlockByRangeResponse(
475
475
  if (i < blocks.length - 1) {
476
476
  // compare the block root against the next block's parent root
477
477
  const parentRoot = blocks[i + 1].message.parentRoot;
478
- if (Buffer.compare(blockRoot, parentRoot) !== 0) {
478
+ if (!byteArrayEquals(blockRoot, parentRoot)) {
479
479
  throw new DownloadByRangeError(
480
480
  {
481
481
  code: DownloadByRangeErrorCode.PARENT_ROOT_MISMATCH,
@@ -9,7 +9,7 @@ import {
9
9
  isForkPostFulu,
10
10
  } from "@lodestar/params";
11
11
  import {BeaconBlockBody, BlobIndex, ColumnIndex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
12
- import {LodestarError, fromHex, prettyPrintIndices, toHex, toRootHex} from "@lodestar/utils";
12
+ import {LodestarError, byteArrayEquals, fromHex, prettyPrintIndices, toHex, toRootHex} from "@lodestar/utils";
13
13
  import {isBlockInputBlobs, isBlockInputColumns} from "../../chain/blocks/blockInput/blockInput.js";
14
14
  import {BlockInputSource, IBlockInput} from "../../chain/blocks/blockInput/types.js";
15
15
  import {ChainEventEmitter} from "../../chain/emitter.js";
@@ -19,7 +19,6 @@ import {validateBlockDataColumnSidecars} from "../../chain/validation/dataColumn
19
19
  import {INetwork} from "../../network/interface.js";
20
20
  import {PeerSyncMeta} from "../../network/peers/peersData.js";
21
21
  import {prettyPrintPeerIdStr} from "../../network/util.js";
22
- import {byteArrayEquals} from "../../util/bytes.js";
23
22
  import {PeerIdStr} from "../../util/peerId.js";
24
23
  import {WarnResult} from "../../util/wrapError.js";
25
24
  import {
@@ -1,3 +0,0 @@
1
- import { Root } from "@lodestar/types";
2
- export declare function byteArrayEquals(a: Uint8Array | Root, b: Uint8Array | Root): boolean;
3
- //# sourceMappingURL=bytes.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bytes.d.ts","sourceRoot":"","sources":["../../src/util/bytes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,iBAAiB,CAAC;AAErC,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,GAAG,IAAI,EAAE,CAAC,EAAE,UAAU,GAAG,IAAI,GAAG,OAAO,CAQnF"}
package/lib/util/bytes.js DELETED
@@ -1,11 +0,0 @@
1
- export function byteArrayEquals(a, b) {
2
- if (a.length !== b.length) {
3
- return false;
4
- }
5
- for (let i = 0; i < a.length; i++) {
6
- if (a[i] !== b[i])
7
- return false;
8
- }
9
- return true;
10
- }
11
- //# sourceMappingURL=bytes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bytes.js","sourceRoot":"","sources":["../../src/util/bytes.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,eAAe,CAAC,CAAoB,EAAE,CAAoB;IACxE,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IAClC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
package/src/util/bytes.ts DELETED
@@ -1,11 +0,0 @@
1
- import {Root} from "@lodestar/types";
2
-
3
- export function byteArrayEquals(a: Uint8Array | Root, b: Uint8Array | Root): boolean {
4
- if (a.length !== b.length) {
5
- return false;
6
- }
7
- for (let i = 0; i < a.length; i++) {
8
- if (a[i] !== b[i]) return false;
9
- }
10
- return true;
11
- }