@lodestar/beacon-node 1.36.0-rc.2 → 1.36.0-rc.3

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 (50) hide show
  1. package/lib/chain/errors/blobSidecarError.d.ts +5 -0
  2. package/lib/chain/errors/blobSidecarError.d.ts.map +1 -1
  3. package/lib/chain/errors/blobSidecarError.js.map +1 -1
  4. package/lib/chain/errors/dataColumnSidecarError.d.ts +4 -0
  5. package/lib/chain/errors/dataColumnSidecarError.d.ts.map +1 -1
  6. package/lib/chain/errors/dataColumnSidecarError.js.map +1 -1
  7. package/lib/chain/validation/blobSidecar.d.ts +4 -1
  8. package/lib/chain/validation/blobSidecar.d.ts.map +1 -1
  9. package/lib/chain/validation/blobSidecar.js +46 -11
  10. package/lib/chain/validation/blobSidecar.js.map +1 -1
  11. package/lib/chain/validation/dataColumnSidecar.d.ts +4 -1
  12. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  13. package/lib/chain/validation/dataColumnSidecar.js +33 -5
  14. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  15. package/lib/network/gossip/gossipsub.d.ts.map +1 -1
  16. package/lib/network/gossip/gossipsub.js +6 -1
  17. package/lib/network/gossip/gossipsub.js.map +1 -1
  18. package/lib/network/gossip/interface.d.ts +2 -0
  19. package/lib/network/gossip/interface.d.ts.map +1 -1
  20. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  21. package/lib/network/processor/gossipHandlers.js +14 -0
  22. package/lib/network/processor/gossipHandlers.js.map +1 -1
  23. package/lib/network/processor/gossipValidatorFn.d.ts.map +1 -1
  24. package/lib/network/processor/gossipValidatorFn.js +3 -2
  25. package/lib/network/processor/gossipValidatorFn.js.map +1 -1
  26. package/lib/network/processor/types.d.ts +2 -0
  27. package/lib/network/processor/types.d.ts.map +1 -1
  28. package/lib/sync/unknownBlock.js +1 -1
  29. package/lib/sync/unknownBlock.js.map +1 -1
  30. package/lib/sync/utils/downloadByRange.d.ts +1 -2
  31. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  32. package/lib/sync/utils/downloadByRange.js +4 -2
  33. package/lib/sync/utils/downloadByRange.js.map +1 -1
  34. package/lib/sync/utils/downloadByRoot.d.ts +8 -14
  35. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  36. package/lib/sync/utils/downloadByRoot.js +18 -33
  37. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  38. package/package.json +14 -14
  39. package/src/chain/errors/blobSidecarError.ts +12 -2
  40. package/src/chain/errors/dataColumnSidecarError.ts +11 -2
  41. package/src/chain/validation/blobSidecar.ts +54 -10
  42. package/src/chain/validation/dataColumnSidecar.ts +43 -4
  43. package/src/network/gossip/gossipsub.ts +7 -1
  44. package/src/network/gossip/interface.ts +2 -0
  45. package/src/network/processor/gossipHandlers.ts +15 -0
  46. package/src/network/processor/gossipValidatorFn.ts +15 -2
  47. package/src/network/processor/types.ts +2 -0
  48. package/src/sync/unknownBlock.ts +1 -1
  49. package/src/sync/utils/downloadByRange.ts +15 -6
  50. package/src/sync/utils/downloadByRoot.ts +22 -56
@@ -37,7 +37,6 @@ export type DownloadByRangeResponses = {
37
37
 
38
38
  export type DownloadAndCacheByRangeProps = DownloadByRangeRequests & {
39
39
  config: ChainForkConfig;
40
- cache: SeenBlockInput;
41
40
  network: INetwork;
42
41
  logger: Logger;
43
42
  peerIdStr: string;
@@ -203,7 +202,7 @@ export async function downloadByRange({
203
202
  blocksRequest,
204
203
  blobsRequest,
205
204
  columnsRequest,
206
- }: Omit<DownloadAndCacheByRangeProps, "cache">): Promise<WarnResult<ValidatedResponses, DownloadByRangeError>> {
205
+ }: DownloadAndCacheByRangeProps): Promise<WarnResult<ValidatedResponses, DownloadByRangeError>> {
207
206
  let response: DownloadByRangeResponses;
208
207
  try {
209
208
  response = await requestByRange({
@@ -555,9 +554,13 @@ export async function validateBlobsByRangeResponse(
555
554
  }
556
555
 
557
556
  validateSidecarsPromises.push(
558
- validateBlockBlobSidecars(block.message.slot, blockRoot, blockKzgCommitments.length, blockBlobSidecars).then(
559
- () => ({blockRoot, blobSidecars: blockBlobSidecars})
560
- )
557
+ validateBlockBlobSidecars(
558
+ null, // do not pass chain here so we do not validate header signature
559
+ block.message.slot,
560
+ blockRoot,
561
+ blockKzgCommitments.length,
562
+ blockBlobSidecars
563
+ ).then(() => ({blockRoot, blobSidecars: blockBlobSidecars}))
561
564
  );
562
565
  }
563
566
 
@@ -768,7 +771,13 @@ export async function validateColumnsByRangeResponse(
768
771
  }
769
772
 
770
773
  validationPromises.push(
771
- validateBlockDataColumnSidecars(slot, blockRoot, blobCount, columnSidecars).then(() => ({
774
+ validateBlockDataColumnSidecars(
775
+ null, // do not pass chain here so we do not validate header signature
776
+ slot,
777
+ blockRoot,
778
+ blobCount,
779
+ columnSidecars
780
+ ).then(() => ({
772
781
  blockRoot,
773
782
  columnSidecars,
774
783
  }))
@@ -9,11 +9,11 @@ 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, prettyBytes, prettyPrintIndices, toHex, toRootHex} from "@lodestar/utils";
12
+ import {LodestarError, 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";
16
- import {SeenBlockInput} from "../../chain/seenCache/seenGossipBlockInput.js";
16
+ import {IBeaconChain} from "../../chain/interface.ts";
17
17
  import {validateBlockBlobSidecars} from "../../chain/validation/blobSidecar.js";
18
18
  import {validateBlockDataColumnSidecars} from "../../chain/validation/dataColumnSidecar.js";
19
19
  import {INetwork} from "../../network/interface.js";
@@ -32,6 +32,7 @@ import {
32
32
 
33
33
  export type FetchByRootCoreProps = {
34
34
  config: ChainForkConfig;
35
+ chain: IBeaconChain | null; // null for testing purposes
35
36
  network: INetwork;
36
37
  peerMeta: PeerSyncMeta;
37
38
  };
@@ -63,13 +64,13 @@ export type FetchByRootResponses = {
63
64
 
64
65
  export type DownloadByRootProps = FetchByRootCoreProps & {
65
66
  cacheItem: BlockInputSyncCacheItem;
66
- seenCache: SeenBlockInput;
67
+ chain: IBeaconChain;
67
68
  emitter: ChainEventEmitter;
68
69
  };
69
70
 
70
71
  export async function downloadByRoot({
71
72
  config,
72
- seenCache,
73
+ chain,
73
74
  network,
74
75
  emitter,
75
76
  peerMeta,
@@ -84,6 +85,7 @@ export async function downloadByRoot({
84
85
  warnings,
85
86
  } = await fetchByRoot({
86
87
  config,
88
+ chain,
87
89
  network,
88
90
  cacheItem,
89
91
  blockRoot,
@@ -103,7 +105,7 @@ export async function downloadByRoot({
103
105
  });
104
106
  }
105
107
  } else {
106
- blockInput = seenCache.getByBlock({
108
+ blockInput = chain.seenBlockInputCache.getByBlock({
107
109
  block,
108
110
  peerIdStr,
109
111
  blockRootHex: rootHex,
@@ -119,7 +121,7 @@ export async function downloadByRoot({
119
121
  if (!blobSidecars) {
120
122
  throw new DownloadByRootError({
121
123
  code: DownloadByRootErrorCode.MISSING_BLOB_RESPONSE,
122
- blockRoot: prettyBytes(rootHex),
124
+ blockRoot: rootHex,
123
125
  peer: peerIdStr,
124
126
  });
125
127
  }
@@ -157,7 +159,7 @@ export async function downloadByRoot({
157
159
  if (!columnSidecars) {
158
160
  throw new DownloadByRootError({
159
161
  code: DownloadByRootErrorCode.MISSING_COLUMN_RESPONSE,
160
- blockRoot: prettyBytes(rootHex),
162
+ blockRoot: rootHex,
161
163
  peer: peerIdStr,
162
164
  });
163
165
  }
@@ -210,6 +212,7 @@ export async function downloadByRoot({
210
212
 
211
213
  export async function fetchByRoot({
212
214
  config,
215
+ chain,
213
216
  network,
214
217
  peerMeta,
215
218
  blockRoot,
@@ -237,6 +240,7 @@ export async function fetchByRoot({
237
240
  if (isBlockInputBlobs(cacheItem.blockInput)) {
238
241
  blobSidecars = await fetchAndValidateBlobs({
239
242
  config,
243
+ chain,
240
244
  network,
241
245
  peerIdStr,
242
246
  forkName: forkName as ForkPreFulu,
@@ -248,6 +252,7 @@ export async function fetchByRoot({
248
252
  if (isBlockInputColumns(cacheItem.blockInput)) {
249
253
  columnSidecarResult = await fetchAndValidateColumns({
250
254
  config,
255
+ chain,
251
256
  network,
252
257
  peerMeta,
253
258
  forkName: forkName as ForkPostFulu,
@@ -268,6 +273,7 @@ export async function fetchByRoot({
268
273
  if (isForkPostFulu(forkName)) {
269
274
  columnSidecarResult = await fetchAndValidateColumns({
270
275
  config,
276
+ chain,
271
277
  network,
272
278
  peerMeta,
273
279
  forkName,
@@ -280,6 +286,7 @@ export async function fetchByRoot({
280
286
  const blobCount = commitments.length;
281
287
  blobSidecars = await fetchAndValidateBlobs({
282
288
  config,
289
+ chain,
283
290
  network,
284
291
  peerIdStr,
285
292
  forkName: forkName as ForkPreFulu,
@@ -305,14 +312,14 @@ export async function fetchAndValidateBlock({
305
312
  network,
306
313
  peerIdStr,
307
314
  blockRoot,
308
- }: FetchByRootAndValidateBlockProps): Promise<SignedBeaconBlock> {
315
+ }: Omit<FetchByRootAndValidateBlockProps, "chain">): Promise<SignedBeaconBlock> {
309
316
  const response = await network.sendBeaconBlocksByRoot(peerIdStr, [blockRoot]);
310
317
  const block = response.at(0)?.data;
311
318
  if (!block) {
312
319
  throw new DownloadByRootError({
313
320
  code: DownloadByRootErrorCode.MISSING_BLOCK_RESPONSE,
314
321
  peer: prettyPrintPeerIdStr(peerIdStr),
315
- blockRoot: prettyBytes(blockRoot),
322
+ blockRoot: toRootHex(blockRoot),
316
323
  });
317
324
  }
318
325
  const receivedRoot = config.getForkTypes(block.message.slot).BeaconBlock.hashTreeRoot(block.message);
@@ -321,8 +328,8 @@ export async function fetchAndValidateBlock({
321
328
  {
322
329
  code: DownloadByRootErrorCode.MISMATCH_BLOCK_ROOT,
323
330
  peer: prettyPrintPeerIdStr(peerIdStr),
324
- requestedBlockRoot: prettyBytes(blockRoot),
325
- receivedBlockRoot: prettyBytes(toRootHex(receivedRoot)),
331
+ requestedBlockRoot: toRootHex(blockRoot),
332
+ receivedBlockRoot: toRootHex(receivedRoot),
326
333
  },
327
334
  "block does not match requested root"
328
335
  );
@@ -331,6 +338,7 @@ export async function fetchAndValidateBlock({
331
338
  }
332
339
 
333
340
  export async function fetchAndValidateBlobs({
341
+ chain,
334
342
  network,
335
343
  peerIdStr,
336
344
  blockRoot,
@@ -344,7 +352,7 @@ export async function fetchAndValidateBlobs({
344
352
  missing,
345
353
  });
346
354
 
347
- await validateBlockBlobSidecars(block.message.slot, blockRoot, missing.length, blobSidecars);
355
+ await validateBlockBlobSidecars(chain, block.message.slot, blockRoot, missing.length, blobSidecars);
348
356
 
349
357
  return blobSidecars;
350
358
  }
@@ -368,6 +376,7 @@ export async function fetchBlobsByRoot({
368
376
  }
369
377
 
370
378
  export async function fetchAndValidateColumns({
379
+ chain,
371
380
  network,
372
381
  peerMeta,
373
382
  block,
@@ -438,7 +447,7 @@ export async function fetchAndValidateColumns({
438
447
  );
439
448
  }
440
449
 
441
- await validateBlockDataColumnSidecars(slot, blockRoot, blobCount, columnSidecars);
450
+ await validateBlockDataColumnSidecars(chain, slot, blockRoot, blobCount, columnSidecars);
442
451
 
443
452
  return {result: columnSidecars, warnings: warnings.length > 0 ? warnings : null};
444
453
  }
@@ -456,49 +465,6 @@ export async function fetchColumnsByRoot({
456
465
  return await network.sendDataColumnSidecarsByRoot(peerMeta.peerId, [{blockRoot, columns: missing}]);
457
466
  }
458
467
 
459
- // TODO(fulu) not in use, remove?
460
- export type ValidateColumnSidecarsProps = Pick<
461
- FetchByRootAndValidateColumnsProps,
462
- "config" | "peerMeta" | "blockRoot" | "missing"
463
- > & {
464
- slot: number;
465
- blobCount: number;
466
- needed?: fulu.DataColumnSidecars;
467
- needToPublish?: fulu.DataColumnSidecars;
468
- };
469
-
470
- // TODO(fulu) not in use, remove?
471
- export async function validateColumnSidecars({
472
- peerMeta,
473
- slot,
474
- blockRoot,
475
- blobCount,
476
- missing,
477
- needed = [],
478
- needToPublish = [],
479
- }: ValidateColumnSidecarsProps): Promise<void> {
480
- const requestedIndices = missing;
481
- const extraIndices: number[] = [];
482
- for (const columnSidecar of needed) {
483
- if (!requestedIndices.includes(columnSidecar.index)) {
484
- extraIndices.push(columnSidecar.index);
485
- }
486
- }
487
- if (extraIndices.length > 0) {
488
- throw new DownloadByRootError(
489
- {
490
- code: DownloadByRootErrorCode.EXTRA_SIDECAR_RECEIVED,
491
- peer: prettyPrintPeerIdStr(peerMeta.peerId),
492
- slot,
493
- blockRoot: prettyBytes(blockRoot),
494
- invalidIndices: prettyPrintIndices(extraIndices),
495
- },
496
- "Received a columnSidecar that was not requested"
497
- );
498
- }
499
- await validateBlockDataColumnSidecars(slot, blockRoot, blobCount, [...needed, ...needToPublish]);
500
- }
501
-
502
468
  export enum DownloadByRootErrorCode {
503
469
  MISMATCH_BLOCK_ROOT = "DOWNLOAD_BY_ROOT_ERROR_MISMATCH_BLOCK_ROOT",
504
470
  EXTRA_SIDECAR_RECEIVED = "DOWNLOAD_BY_ROOT_ERROR_EXTRA_SIDECAR_RECEIVED",