@lodestar/beacon-node 1.45.0-dev.d16fa2b13a → 1.45.0-dev.d5aff60d6c

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 (31) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +2 -3
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
  5. package/lib/chain/blocks/utils/chainSegment.js +5 -13
  6. package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
  7. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +1 -1
  8. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  9. package/lib/chain/blocks/verifyBlocksSanityChecks.js +1 -1
  10. package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
  11. package/lib/chain/errors/blockError.d.ts +6 -41
  12. package/lib/chain/errors/blockError.d.ts.map +1 -1
  13. package/lib/chain/errors/blockError.js +4 -23
  14. package/lib/chain/errors/blockError.js.map +1 -1
  15. package/lib/chain/validation/block.js +3 -3
  16. package/lib/chain/validation/block.js.map +1 -1
  17. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  18. package/lib/network/processor/gossipHandlers.js +6 -12
  19. package/lib/network/processor/gossipHandlers.js.map +1 -1
  20. package/lib/sync/unknownBlock.d.ts.map +1 -1
  21. package/lib/sync/unknownBlock.js +2 -7
  22. package/lib/sync/unknownBlock.js.map +1 -1
  23. package/package.json +14 -14
  24. package/src/api/impl/beacon/blocks/index.ts +2 -3
  25. package/src/chain/blocks/utils/chainSegment.ts +5 -16
  26. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +1 -1
  27. package/src/chain/blocks/verifyBlocksSanityChecks.ts +1 -1
  28. package/src/chain/errors/blockError.ts +7 -41
  29. package/src/chain/validation/block.ts +3 -3
  30. package/src/network/processor/gossipHandlers.ts +6 -12
  31. package/src/sync/unknownBlock.ts +2 -8
@@ -86,22 +86,11 @@ export function assertLinearChainSegment(
86
86
  // Maybe the previous slot's FULL envelope was orphaned — try falling back.
87
87
  // If even prevExecHash doesn't match, the segment is non-linear.
88
88
  if (bidParentHash !== prevExecHash) {
89
- // i === 0 compares against the seeded fork-choice parent (segment boundary); i > 0
90
- // compares against the in-segment predecessor's payload (broken link inside the segment).
91
- throw new BlockError(
92
- block,
93
- i === 0
94
- ? {
95
- code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN,
96
- parentRoot: toRootHex(block.message.parentRoot),
97
- parentBlockHash: bidParentHash,
98
- }
99
- : {
100
- code: BlockErrorCode.NON_LINEAR_PAYLOAD_ROOTS,
101
- parentBlockHash: bidParentHash,
102
- expectedBlockHash: currentExecHash,
103
- }
104
- );
89
+ throw new BlockError(block, {
90
+ code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN,
91
+ parentRoot: toRootHex(block.message.parentRoot),
92
+ parentBlockHash: bidParentHash,
93
+ });
105
94
  }
106
95
  if (lastFullSlot !== null && payloadEnvelopes !== null) {
107
96
  const orphanedInput = payloadEnvelopes.get(lastFullSlot);
@@ -201,7 +201,7 @@ export async function verifyBlockExecutionPayload(
201
201
  invalidateFromParentBlockHash: toRootHex(executionPayloadEnabled.parentHash),
202
202
  };
203
203
  const execError = new BlockError(block, {
204
- code: BlockErrorCode.EXECUTION_ENGINE_INVALID,
204
+ code: BlockErrorCode.EXECUTION_ENGINE_ERROR,
205
205
  execStatus: execResult.status,
206
206
  errorMessage: execResult.validationError ?? "",
207
207
  });
@@ -94,7 +94,7 @@ export function verifyBlocksSanityChecks(
94
94
  const parentRoot = toRootHex(block.message.parentRoot);
95
95
  const parentBlockDefaultStatus = chain.forkChoice.getBlockHexDefaultStatus(parentRoot);
96
96
  if (!parentBlockDefaultStatus) {
97
- throw new BlockError(block, {code: BlockErrorCode.PARENT_BLOCK_UNKNOWN, parentRoot});
97
+ throw new BlockError(block, {code: BlockErrorCode.PARENT_UNKNOWN, parentRoot});
98
98
  }
99
99
 
100
100
  parentBlock = parentBlockDefaultStatus;
@@ -8,10 +8,8 @@ import {GossipActionError} from "./gossipValidation.js";
8
8
  export enum BlockErrorCode {
9
9
  /** The prestate cannot be fetched */
10
10
  PRESTATE_MISSING = "BLOCK_ERROR_PRESTATE_MISSING",
11
- /**
12
- * The first block of a chain segment references a parentRoot unknown to fork-choice.
13
- */
14
- PARENT_BLOCK_UNKNOWN = "BLOCK_ERROR_PARENT_BLOCK_UNKNOWN",
11
+ /** The parent block was unknown. */
12
+ PARENT_UNKNOWN = "BLOCK_ERROR_PARENT_UNKNOWN",
15
13
  /** The block slot is greater than the present slot. */
16
14
  FUTURE_SLOT = "BLOCK_ERROR_FUTURE_SLOT",
17
15
  /** The block state_root does not match the generated state. */
@@ -40,10 +38,7 @@ export enum BlockErrorCode {
40
38
  NOT_FINALIZED_DESCENDANT = "BLOCK_ERROR_NOT_FINALIZED_DESCENDANT",
41
39
  /** The provided block is from an later slot than its parent. */
42
40
  NOT_LATER_THAN_PARENT = "BLOCK_ERROR_NOT_LATER_THAN_PARENT",
43
- /**
44
- * A block in the middle of a chain segment does not set its parentRoot to the previous block's root
45
- * (broken parent-root link inside the segment).
46
- */
41
+ /** At least one block in the chain segment did not have it's parent root set to the root of the prior block. */
47
42
  NON_LINEAR_PARENT_ROOTS = "BLOCK_ERROR_NON_LINEAR_PARENT_ROOTS",
48
43
  /** The slots of the blocks in the chain segment were not strictly increasing. */
49
44
  NON_LINEAR_SLOTS = "BLOCK_ERROR_NON_LINEAR_SLOTS",
@@ -66,12 +61,6 @@ export enum BlockErrorCode {
66
61
  TRANSACTIONS_TOO_BIG = "BLOCK_ERROR_TRANSACTIONS_TOO_BIG",
67
62
  /** Execution engine is unavailable, syncing, or api call errored. Peers must not be downscored on this code */
68
63
  EXECUTION_ENGINE_ERROR = "BLOCK_ERROR_EXECUTION_ERROR",
69
- /**
70
- * Execution engine returned a definitive INVALID verdict on the payload. Unlike
71
- * EXECUTION_ENGINE_ERROR this is evidence about the data itself, not a local malfunction, so
72
- * whoever served the block MAY be downscored. Mirrors PayloadErrorCode.EXECUTION_ENGINE_INVALID.
73
- */
74
- EXECUTION_ENGINE_INVALID = "BLOCK_ERROR_EXECUTION_INVALID",
75
64
  /** The blobs are unavailable */
76
65
  DATA_UNAVAILABLE = "BLOCK_ERROR_DATA_UNAVAILABLE",
77
66
  /** Block contains too many kzg commitments */
@@ -82,16 +71,8 @@ export enum BlockErrorCode {
82
71
  TOO_MANY_BLOCK_OPERATIONS = "BLOCK_ERROR_TOO_MANY_BLOCK_OPERATIONS",
83
72
  /** The parent block's execution payload has been verified as invalid */
84
73
  PARENT_EXECUTION_INVALID = "BLOCK_ERROR_PARENT_EXECUTION_INVALID",
85
- /**
86
- * [gloas] The first block of a chain segment references a parent execution payload
87
- * (bid.parent_block_hash) unknown to fork-choice (segment boundary).
88
- */
74
+ /** The block's parent execution payload (defined by bid.parent_block_hash) has not been seen */
89
75
  PARENT_PAYLOAD_UNKNOWN = "BLOCK_ERROR_PARENT_PAYLOAD_UNKNOWN",
90
- /**
91
- * [gloas] A block in the middle of a chain segment has a bid.parent_block_hash that does not chain onto the
92
- * previous block's execution payload (broken payload link inside the segment).
93
- */
94
- NON_LINEAR_PAYLOAD_ROOTS = "BLOCK_ERROR_NON_LINEAR_PAYLOAD_ROOTS",
95
76
  /** An execution payload envelope in the chain segment references a block root that does not match its slot's block */
96
77
  ENVELOPE_BLOCK_ROOT_MISMATCH = "BLOCK_ERROR_ENVELOPE_BLOCK_ROOT_MISMATCH",
97
78
  }
@@ -101,18 +82,9 @@ type ExecutionErrorStatus = Exclude<
101
82
  ExecutionPayloadStatus.VALID | ExecutionPayloadStatus.ACCEPTED | ExecutionPayloadStatus.SYNCING
102
83
  >;
103
84
 
104
- /**
105
- * Statuses where the execution engine could NOT render a verdict on the payload: it is unreachable
106
- * (UNAVAILABLE), errored (ELERROR), or returned a malformed/client-specific response
107
- * (INVALID_BLOCK_HASH, dropped from engine_newPayloadV2+). None of these are evidence about the
108
- * data, so peers must not be downscored on them. A definitive INVALID carries
109
- * BlockErrorCode.EXECUTION_ENGINE_INVALID instead.
110
- */
111
- type ExecutionEngineErrorStatus = Exclude<ExecutionErrorStatus, ExecutionPayloadStatus.INVALID>;
112
-
113
85
  export type BlockErrorType =
114
86
  | {code: BlockErrorCode.PRESTATE_MISSING; error: Error}
115
- | {code: BlockErrorCode.PARENT_BLOCK_UNKNOWN; parentRoot: RootHex}
87
+ | {code: BlockErrorCode.PARENT_UNKNOWN; parentRoot: RootHex}
116
88
  | {code: BlockErrorCode.FUTURE_SLOT; blockSlot: Slot; currentSlot: Slot}
117
89
  | {code: BlockErrorCode.STATE_ROOT_MISMATCH}
118
90
  | {code: BlockErrorCode.GENESIS_BLOCK}
@@ -144,19 +116,13 @@ export type BlockErrorType =
144
116
  | {code: BlockErrorCode.TOO_MUCH_GAS_USED; gasUsed: number; gasLimit: number}
145
117
  | {code: BlockErrorCode.SAME_PARENT_HASH; blockHash: RootHex}
146
118
  | {code: BlockErrorCode.TRANSACTIONS_TOO_BIG; size: number; max: number}
147
- | {code: BlockErrorCode.EXECUTION_ENGINE_ERROR; execStatus: ExecutionEngineErrorStatus; errorMessage: string}
148
- | {
149
- code: BlockErrorCode.EXECUTION_ENGINE_INVALID;
150
- execStatus: ExecutionPayloadStatus.INVALID;
151
- errorMessage: string;
152
- }
119
+ | {code: BlockErrorCode.EXECUTION_ENGINE_ERROR; execStatus: ExecutionErrorStatus; errorMessage: string}
153
120
  | {code: BlockErrorCode.DATA_UNAVAILABLE}
154
121
  | {code: BlockErrorCode.TOO_MANY_KZG_COMMITMENTS; blobKzgCommitmentsLen: number; commitmentLimit: number}
155
122
  | {code: BlockErrorCode.BID_PARENT_ROOT_MISMATCH; bidParentRoot: RootHex; blockParentRoot: RootHex}
156
123
  | {code: BlockErrorCode.TOO_MANY_BLOCK_OPERATIONS; name: string; count: number; limit: number}
157
124
  | {code: BlockErrorCode.PARENT_EXECUTION_INVALID; parentRoot: RootHex}
158
- | {code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN; parentRoot: RootHex; parentBlockHash: RootHex}
159
- | {code: BlockErrorCode.NON_LINEAR_PAYLOAD_ROOTS; parentBlockHash: RootHex; expectedBlockHash: RootHex};
125
+ | {code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN; parentRoot: RootHex; parentBlockHash: RootHex};
160
126
 
161
127
  export class BlockGossipError extends GossipActionError<BlockErrorType> {}
162
128
 
@@ -104,8 +104,8 @@ export async function validateGossipBlock(
104
104
  // 2. The parent is unknown to us, we probably want to download it since it might actually
105
105
  // descend from the finalized root.
106
106
  // (Non-Lighthouse): Since we prune all blocks non-descendant from finalized checking the `db.block` database won't be useful to guard
107
- // against known bad fork blocks, so we throw PARENT_BLOCK_UNKNOWN for cases (1) and (2)
108
- throw new BlockGossipError(GossipAction.IGNORE, {code: BlockErrorCode.PARENT_BLOCK_UNKNOWN, parentRoot});
107
+ // against known bad fork blocks, so we throw PARENT_UNKNOWN for cases (1) and (2)
108
+ throw new BlockGossipError(GossipAction.IGNORE, {code: BlockErrorCode.PARENT_UNKNOWN, parentRoot});
109
109
  }
110
110
 
111
111
  // [IGNORE] The block's parent (defined by `block.parent_root`) passes all validation
@@ -244,7 +244,7 @@ export async function validateGossipBlock(
244
244
  const blockState = await chain.regen
245
245
  .getPreState(block, {dontTransferCache: true}, RegenCaller.validateGossipBlock)
246
246
  .catch(() => {
247
- throw new BlockGossipError(GossipAction.IGNORE, {code: BlockErrorCode.PARENT_BLOCK_UNKNOWN, parentRoot});
247
+ throw new BlockGossipError(GossipAction.IGNORE, {code: BlockErrorCode.PARENT_UNKNOWN, parentRoot});
248
248
  });
249
249
 
250
250
  // in forky condition, make sure to populate ShufflingCache with regened state
@@ -176,7 +176,7 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
176
176
 
177
177
  // optimistically add gossip block to the seen cache
178
178
  // if validation fails, we will NOT forward this gossip block to peers
179
- // - if PARENT_BLOCK_UNKNOWN error, blockInput will then be queued inside BlockInputSync. If the gossip block is really invalid, it will be pruned there
179
+ // - if PARENT_UNKNOWN error, blockInput will then be queued inside BlockInputSync. If the gossip block is really invalid, it will be pruned there
180
180
  // - if other validator errors, blockInput will stay in the seen cache and will be pruned on finalization
181
181
  const blockInput = chain.seenBlockInputCache.getByBlock({
182
182
  block: signedBlock,
@@ -187,7 +187,7 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
187
187
  });
188
188
 
189
189
  // Optimistically seed the payload-envelope cache too, mirroring seenBlockInputCache above.
190
- // This ensures we have PayloadEnvelopeInput, even through "PARENT_BLOCK_UNKNOWN" error
190
+ // This ensures we have PayloadEnvelopeInput, even through "PARENT_UNKNOWN" error
191
191
  // see https://github.com/ChainSafe/lodestar/issues/9475
192
192
  if (isForkPostGloas(fork)) {
193
193
  chain.seenPayloadEnvelopeInputCache.add({
@@ -227,8 +227,7 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
227
227
  if (e instanceof BlockGossipError) {
228
228
  logger.debug("Gossip block has error", {slot, root: blockShortHex, code: e.type.code});
229
229
  if (
230
- (e.type.code === BlockErrorCode.PARENT_BLOCK_UNKNOWN ||
231
- e.type.code === BlockErrorCode.PARENT_PAYLOAD_UNKNOWN) &&
230
+ (e.type.code === BlockErrorCode.PARENT_UNKNOWN || e.type.code === BlockErrorCode.PARENT_PAYLOAD_UNKNOWN) &&
232
231
  blockInput
233
232
  ) {
234
233
  chain.emitter.emit(ChainEvent.blockUnknownParent, {
@@ -662,19 +661,14 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
662
661
  break;
663
662
  }
664
663
  // ALREADY_KNOWN should not happen with ignoreIfKnown=true above
665
- // PARENT_BLOCK_UNKNOWN should not happen, we handled this in validateBeaconBlock() function above
664
+ // PARENT_UNKNOWN should not happen, we handled this in validateBeaconBlock() function above
666
665
  case BlockErrorCode.ALREADY_KNOWN:
667
- case BlockErrorCode.PARENT_BLOCK_UNKNOWN:
666
+ case BlockErrorCode.PARENT_UNKNOWN:
668
667
  case BlockErrorCode.PRESTATE_MISSING:
669
668
  case BlockErrorCode.EXECUTION_ENGINE_ERROR:
670
- // Errors might indicate an issue with our node or the connected EL client.
669
+ // Errors might indicate an issue with our node or the connected EL client
671
670
  logLevel = LogLevel.error;
672
671
  break;
673
- case BlockErrorCode.EXECUTION_ENGINE_INVALID:
674
- // the peer served a bad block
675
- core.reportPeer(peerIdStr, PeerAction.LowToleranceError, "ExecutionEngineInvalid");
676
- logLevel = LogLevel.warn;
677
- break;
678
672
  default:
679
673
  // TODO: Should it use PeerId or string?
680
674
  core.reportPeer(peerIdStr, PeerAction.LowToleranceError, "BadGossipBlock");
@@ -819,7 +819,7 @@ export class BlockInputSync {
819
819
  // case BlockErrorCode.ALREADY_KNOWN:
820
820
  // case BlockErrorCode.GENESIS_BLOCK:
821
821
 
822
- case BlockErrorCode.PARENT_BLOCK_UNKNOWN:
822
+ case BlockErrorCode.PARENT_UNKNOWN:
823
823
  case BlockErrorCode.PRESTATE_MISSING:
824
824
  // Should not happen, mark as downloaded to try again latter
825
825
  this.logger.debug("Attempted to process block but its parent was still unknown", errorData, res.err);
@@ -841,16 +841,10 @@ export class BlockInputSync {
841
841
 
842
842
  case BlockErrorCode.EXECUTION_ENGINE_ERROR:
843
843
  // Removing the block(s) without penalizing the peers, hoping for EL to
844
- // recover on a latter download + verify attempt.
844
+ // recover on a latter download + verify attempt
845
845
  this.removeAllDescendants(pendingBlock);
846
846
  break;
847
847
 
848
- case BlockErrorCode.EXECUTION_ENGINE_INVALID:
849
- // the peer served a bad block
850
- this.logger.debug("Execution engine rejected block from unknown parent sync", errorData, res.err);
851
- this.removeAndDownScoreAllDescendants(pendingBlock);
852
- break;
853
-
854
848
  default:
855
849
  // Block is not correct with respect to our chain. Log error loudly
856
850
  this.logger.debug("Error processing block from unknown parent sync", errorData, res.err);